Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions
@@ -0,0 +1,72 @@
#include <precomp.h>
#include "SelItemList.h"
#include "listwnd.h"
#define SELITEMEXPAND 2040
SelItemList::SelItemList(ListWnd *parent) :
listwnd(parent), list(SELITEMEXPAND), num_selected(0) { }
void SelItemList::setSelected(int pos, int selected, int cb)
{
int s = list.getSize();
if (pos >= s)
{
if (!selected)
{
// turning off something that's out of range is a no-brainer
return ;
}
s = ((s / SELITEMEXPAND) + 1) * SELITEMEXPAND;
list.setSize(s);
}
char *l = list.getMemory();
if (selected)
{
// quick and dirty way to prevent more than one item from
// ever being selected?
if (listwnd->getPreventMultipleSelection())
{
listwnd->deselectAll(cb);
}
if (!isSelected(pos))
{
l[pos] = 1;
num_selected++;
if (cb) listwnd->itemSelection(pos, TRUE);
listwnd->invalidateItem(pos);
}
}
else
{
if (isSelected(pos))
{
l[pos] = 0;
num_selected--;
if (cb) listwnd->itemSelection(pos, FALSE);
listwnd->invalidateItem(pos);
}
}
}
int SelItemList::isSelected(int pos)
{
if (pos >= list.getSize()) return 0;
return list.getMemory()[pos];
}
int SelItemList::getNumSelected() { return num_selected; }
void SelItemList::deleteByPos(int pos)
{
ASSERT(pos >= 0);
int s = list.getSize();
if (pos >= s) return ;
num_selected -= isSelected(pos);
char *m = list.getMemory() + pos;
MEMCPY(m, m + 1, s - (pos + 1));
}
void SelItemList::deselectAll()
{ // for internal use, doesn't send callbacks
list.zeroMemory();
num_selected = 0;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef NULLSOFT_SELITEMLISTH
#define NULLSOFT_SELITEMLISTH
class ListWnd;
#define SELITEMEXPAND 2040
//note to whoever redid this as a bitlist
// a) this is pointlessly slow as a bitlist given the memory used
// b) perhaps you should investigate bitlist.h
class SelItemList
{
public:
SelItemList(ListWnd *parent);
void setSelected(int pos, int selected, int cb=1);
int isSelected(int pos);
int getNumSelected();
void deleteByPos(int pos);
protected:
friend ListWnd;
void deselectAll();
private:
ListWnd *listwnd;
MemBlock<char> list;
int num_selected;
};
#endif
@@ -0,0 +1,287 @@
#include "precomp.h"
#include <api/syscb/api_syscb.h>
#include "abstractwndhold.h"
#include <api/service/svc_enum.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <api/service/svcs/svc_wndcreate.h>
#include <api/script/scriptguid.h>
#include <api/script/objects/c_script/c_guiobject.h>
#include <api/script/objects/c_script/c_group.h>
#include <api/wnd/notifmsg.h>
#define CB_ABSTRACTLOAD 0x1125
AbstractWndHolder::AbstractWndHolder(const wchar_t *grpid, int autoresize) : ServiceWndHolder(NULL, NULL)
{
scripts_enabled = 1;
groupid = grpid;
group_item = NULL;
guid = INVALID_GUID;
group = NULL;
cbreg = 0;
inselfresize = 0;
autoresizefromcontent = autoresize;
allow_deferred_content = 0;
need_deferred_load = 0;
}
AbstractWndHolder::AbstractWndHolder(SkinItem *groupitem, int autoresize) : ServiceWndHolder(NULL, NULL) {
group_item = groupitem;
guid = INVALID_GUID;
group = NULL;
cbreg = 0;
inselfresize = 0;
autoresizefromcontent = autoresize;
allow_deferred_content = 0;
need_deferred_load = 0;
}
AbstractWndHolder::AbstractWndHolder(GUID g, int autoresize) : ServiceWndHolder(NULL, NULL) {
guid = g;
group = NULL;
cbreg = 0;
group_item = NULL;
inselfresize = 0;
autoresizefromcontent = autoresize;
allow_deferred_content = 0;
need_deferred_load = 0;
}
AbstractWndHolder::~AbstractWndHolder() {
if (group) {
#ifdef WASABI_COMPILE_SKIN
WASABI_API_SKIN->group_destroy(group);
#endif
group = NULL;
}
if (cbreg) WASABI_API_SYSCB->syscb_deregisterCallback(this);
}
int AbstractWndHolder::onInit() {
ABSTRACTWNDHOLDER_PARENT::onInit();
createChild();
return 1;
}
ifc_window *AbstractWndHolder::rootwndholder_getRootWnd() {
if (group != NULL) return group;
return ABSTRACTWNDHOLDER_PARENT::rootwndholder_getRootWnd();
}
void AbstractWndHolder::abstract_setContent(const wchar_t *group_id, int autoresize)
{
setBothContent(group_id, INVALID_GUID, autoresize);
}
void AbstractWndHolder::abstract_setContentBySkinItem(SkinItem *item, int autoresize) {
setContentSkinItem(item, autoresize);
}
void AbstractWndHolder::abstract_setContent(GUID g, int autoresize) {
setBothContent(NULL, g, autoresize);
}
void AbstractWndHolder::setBothContent(const wchar_t *group_id, GUID g, int autoresize)
{
group_item = NULL;
if (autoresize != -1)
autoresizefromcontent = autoresize;
if (WCSCASEEQLSAFE(groupid, group_id) || (guid != INVALID_GUID && guid == g)) return;
GUID _g = nsGUID::fromCharW(group_id);
if (g == INVALID_GUID && _g != INVALID_GUID) {
groupid = NULL;
guid = _g;
} else {
groupid = group_id;
guid = g;
}
createChild();
}
void AbstractWndHolder::setContentSkinItem(SkinItem *item, int autoresize)
{
if (autoresize != -1)
autoresizefromcontent = autoresize;
groupid.trunc(0);
guid = INVALID_GUID;
group_item = item;
createChild();
}
int AbstractWndHolder::onGroupChange(const wchar_t *grpid)
{
if (WCSCASEEQLSAFE(groupid, grpid))
{
createChild();
notifyParent(ChildNotify::GROUPRELOAD);
notifyParent(ChildNotify::AUTOWHCHANGED);
}
return 1;
}
void AbstractWndHolder::createChild() {
if (!isInited()) return;
destroyContent();
if (allow_deferred_content && !isVisible())
need_deferred_load = 1;
else
doLoadContent();
}
void AbstractWndHolder::destroyContent()
{
if (group != NULL) {
#ifdef WASABI_COMPILE_SKIN
WASABI_API_SKIN->group_destroy(group);
#endif
if (cbreg) {
WASABI_API_SYSCB->syscb_deregisterCallback(this);
cbreg=0;
}
ABSTRACTWNDHOLDER_PARENT::setChild(NULL, NULL);
}
group = NULL;
}
int AbstractWndHolder::onDeferredCallback(intptr_t p1, intptr_t p2)
{
if (p1 == CB_ABSTRACTLOAD) {
doLoadContent();
return 1;
}
return ABSTRACTWNDHOLDER_PARENT::onDeferredCallback(p1, p2);
}
#include <bfc/util/profiler.h>
void AbstractWndHolder::doLoadContent() {
int didsomething = 0;
need_deferred_load = 0;
if (group_item != NULL) {
#ifdef WASABI_COMPILE_SKIN
group = WASABI_API_SKIN->group_createBySkinItem(group_item, scripts_enabled);
#endif
if (group) {
if (!cbreg) {
WASABI_API_SYSCB->syscb_registerCallback(this);
cbreg=1;
}
group->setParent(this);
group->init(this);
abstract_onNewContent();
didsomething = 1;
}
} else if (!groupid.isempty()) {
#ifdef WASABI_COMPILE_SKIN
group = WASABI_API_SKIN->group_create(groupid, scripts_enabled);
#endif
if (group) {
if (!cbreg) {
WASABI_API_SYSCB->syscb_registerCallback(this);
cbreg=1;
}
group->setParent(this);
group->init(this);
abstract_onNewContent();
didsomething = 1;
}
} else if (guid != INVALID_GUID) {
svc_windowCreate *svc = WindowCreateByGuidEnum(guid).getNext();
ABSTRACTWNDHOLDER_PARENT::setChild(svc->createWindowByGuid(guid, this), svc);
abstract_onNewContent();
didsomething = 1;
}
if (didsomething && isPostOnInit())
{
onResize();
}
}
void AbstractWndHolder::abstract_onNewContent()
{
if (isPostOnInit()) {
ifc_window *w = getDesktopParent();
if (w != NULL) {
if (w->enumMinMaxEnforcer(0)) {
w->signalMinMaxEnforcerChanged();
}
}
}
}
GuiObject *AbstractWndHolder::abstract_findObject(const wchar_t *object_id)
{
ifc_window *w = rootwndholder_getRootWnd();
if (w == NULL) return NULL;
GuiObject *o = static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
return o->guiobject_findObject(object_id);
}
ScriptObject *AbstractWndHolder::abstract_findScriptObject(const wchar_t *object_id)
{
ifc_window *w = rootwndholder_getRootWnd();
if (w == NULL) return NULL;
GuiObject *o = static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
GuiObject *fo = o->guiobject_findObject(object_id);
if (fo != NULL) return fo->guiobject_getScriptObject();
return NULL;
}
GuiObject *AbstractWndHolder::abstract_getContent() {
ifc_window *w = rootwndholder_getRootWnd();
if (w == NULL) return NULL;
return static_cast<GuiObject *>(w->getInterface(guiObjectGuid));
}
ScriptObject *AbstractWndHolder::abstract_getContentScriptObject() {
ifc_window *w = rootwndholder_getRootWnd();
if (w == NULL) return NULL;
return static_cast<ScriptObject *>(w->getInterface(scriptObjectGuid));
}
int AbstractWndHolder::onResize() {
int rt = ABSTRACTWNDHOLDER_PARENT::onResize();
if (group != NULL && abstract_wantAutoResizeFromContent()) {
if (inselfresize) return rt;
inselfresize=1;
int w = group->getPreferences(SUGGESTED_W);
int h = group->getPreferences(SUGGESTED_H);
resize(NOCHANGE, NOCHANGE, w == AUTOWH ? NOCHANGE : w, h == AUTOWH ? NOCHANGE : h);
inselfresize = 0;
}
return rt;
}
void AbstractWndHolder::onSetVisible( int show )
{
ABSTRACTWNDHOLDER_PARENT::onSetVisible( show );
if ( allow_deferred_content )
{
if ( show & need_deferred_load )
{
doLoadContent();
}
if ( !show && !need_deferred_load )
{
destroyContent();
need_deferred_load = 1;
}
}
}
void AbstractWndHolder::abstract_setScriptsEnabled(int en)
{
if (scripts_enabled == en) return;
scripts_enabled = en;
if (group != NULL) {
destroyContent();
doLoadContent();
}
}
int AbstractWndHolder::abstact_getScriptsEnabled() {
return scripts_enabled;
}
@@ -0,0 +1,267 @@
#ifndef __ABSTRACTWNDHOLD_H
#define __ABSTRACTWNDHOLD_H
#include <api/wnd/wndclass/svcwndhold.h>
#include <api/syscb/callbacks/wndcb.h>
class GuiObject;
class ScriptObject;
class SkinItem;
#define ABSTRACTWNDHOLDER_PARENT ServiceWndHolder
/**
The AbstractWndHolder enables you to display deferred content. This means
the content does not actually need to exist at creation. It will be automatically
loaded when it is found.
This class is meant to be derived from. You shouldn't create an AbstractWndHolder
directly to implement this kind of functionality. Please use GuiObjectWnd along
with the setContent() method.
@short An abstracted window holder with deferred content loading.
@author Nullsoft
@ver 1.0
@see GuiObjectWnd
*/
class AbstractWndHolder : public ABSTRACTWNDHOLDER_PARENT, public WndCallbackI {
protected:
// don't create me directly, create a GuiObjectWnd and setContent("group.id") on it
// these are for inheriting and have a deferred content (so if you _were_ using that,
// your findObjects would fail right after init and before abstract_onNewContent)
/**
Sets the group id of the content and the auto resize flag.
Setting the auto resize flag to 1 will enable the automatic resize of
the window according to the size of the content attempting to be
displayed.
@param groupid The content group.
@param _autoresizefromcontent 0, disable auto resize; 1, enable auto resize;
*/
AbstractWndHolder(const wchar_t *groupid=NULL, int _autoresizefromcontent=0);
AbstractWndHolder(SkinItem *groupitem, int _autoresizefromcontent=0);
/**
Finds the group with the matching GUID and uses that group as the content.
This insures you get the exact group and not a replacement.
Setting the auto resize flag to 1 will enable the automatic resize of
the window according to the size of the content attempting to be
displayed.
@param _guid The GUID the content group.
@param _autoresizefromcontent 0, disable auto resize; 1, enable auto resize;
*/
AbstractWndHolder(GUID _guid, int _autoresizefromcontent=0);
public:
/**
Destroys the instance of the group used for content automatically.
*/
virtual ~AbstractWndHolder();
/**
Sets the content group using the group id.
@param groupid The content group id.
@param _autoresizefromcontent -1, no change; 0, disable auto resize; 1, enable auto resize;
*/
virtual void abstract_setContent(const wchar_t *groupid, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
/**
Sets the content group using the group's GUID.
This insures you get the exact group and not a replacement.
@param g The content group's GUID.
@param _autoresizefromcontent -1, no change; 0, disable auto resize; 1, enable auto resize;
*/
virtual void abstract_setContent(GUID g, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
virtual void abstract_setContentBySkinItem(SkinItem *groupitem, int _autoresizefromcontent=-1); // -1 = no change, 0 = false, 1 = true
/**
This event is triggered when the content is loaded or the content changes.
Override it to implement your own handling of this event.
*/
virtual void abstract_onNewContent();
/**
This event is triggered when the content group is changed.
Override it to implement your own handling of this event.
@see abstract_setContant()
@ret 1, if you handle the event;
@param grpid The new group that was set.
*/
virtual int onGroupChange(const wchar_t *grpid);
/**
This event is triggered when the visibility of the window changes.
Override it to implement your own handling of this event.
@see onGroupChange()
@param show 0, hide window; 1, show window;
*/
virtual void onSetVisible(int show);
/**
This event is triggered when the window is being initialized.
Override it to implement your own handling of this event.
@ret 1, if you handle the event;
*/
virtual int onInit();
/**
This event is triggered when the window is resized.
Override it to implement your own handling of this event.
@ret 1, if you handle the event;
*/
virtual int onResize();
/**
Get the api_window.
@ret
*/
ifc_window *rootwndholder_getRootWnd();
/**
Find an object in the content group. This is done via
the object's text id.
@see abstract_findScriptObject()
@ret !NULL, The requested object pointer; NULL, Failed to find object.
@param The id of the object to find.
*/
virtual GuiObject *abstract_findObject(const wchar_t *object_id);
/**
Find a script object in the content group. This is done via the
script object's text id.
@see abstract_findObject()
@ret !NULL, The requested script object pointer; NULL, Failed to find the object.
@param The id of the script object to find.
// TODO: benski> currently unused. cut?
*/
virtual ScriptObject *abstract_findScriptObject(const wchar_t *object_id);
/**
Get the content group.
@see abstract_getContentScriptObject()
@ret A pointer to the content group GuiObject.
*/
virtual GuiObject *abstract_getContent();
/**
Get the content script object.
@see abstract_getContent()
@ret A pointer to the content ScriptObject.
*/
virtual ScriptObject *abstract_getContentScriptObject();
/**
Get the ifc_window that is holding the content group.
@see rootwndholder_getRootWnd()
@ret A pointer to the ifc_window holding the content group.
*/
virtual ifc_window *abstract_getContentRootWnd() { return group; }
/**
Read the auto-resize from content flag.
@see abstract_setAutoResizeFromContent()
@ret 0, disable auto resize; 1, enable auto resize;
@param
*/
virtual int abstract_wantAutoResizeFromContent() { return autoresizefromcontent; }
/**
Set the auto-resize from content flag.
@see abstract_wantAutoResizeFromContent()
@param i 0, disable auto resize; 1, enable auto resize;
*/
virtual void abstract_setAutoResizeFromContent(int i) { autoresizefromcontent = i; }
/**
Set the allow deferred content flag. Allowing deferred content enables content to be
loaded after the window is shown.
@param allow 0, Do not allow; 1, Allow
*/
virtual void abstract_setAllowDeferredContent(int allow) { allow_deferred_content = allow; }
/**
The deferred callback.
@ret 1, If you handle the event.
@param p1
@param p2
*/
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
virtual void setContentSkinItem(SkinItem *groupitem, int autoresize=-1);
virtual void abstract_setScriptsEnabled(int en);
virtual int abstact_getScriptsEnabled();
private:
/**
Creates the child content window when required.
*/
void createChild();
/**
Set Both Content.
@param guid
@param g
@param _autoresizefromcontent
*/
void setBothContent(const wchar_t *guid, GUID g, int _autoresizefromcontent);
/**
Loads the content from the previously specified group.
@see abstract_setContent()
*/
void doLoadContent();
/**
Destroys the instantiated copy of the content group.
*/
void destroyContent();
StringW groupid;
GUID guid;
ifc_window *group;
int cbreg;
int inselfresize;
int autoresizefromcontent;
int allow_deferred_content;
int need_deferred_load;
SkinItem *group_item;
int scripts_enabled = 0;
};
#endif
File diff suppressed because it is too large Load Diff
+155
View File
@@ -0,0 +1,155 @@
#ifndef _APPBARWND_H
#define _APPBARWND_H
#include <bfc/common.h>
#include <shellapi.h>
#include <api/wnd/wndclass/clickwnd.h>
#define APPBARWND_PARENT ClickWnd
#define APPBAR_TOP_ENABLED 1
#define APPBAR_LEFT_ENABLED 2
#define APPBAR_BOTTOM_ENABLED 4
#define APPBAR_RIGHT_ENABLED 8
#define APPABR_ALL_ENABLED (APPBAR_TOP_ENABLED|APPBAR_LEFT_ENABLED|APPBAR_BOTTOM_ENABLED|APPBAR_RIGHT_ENABLED)
#define APPBAR_CALLBACK WM_USER + 1010
#define IDT_AUTOHIDE 0x10000
#define IDT_AUTOUNHIDE 0x10001
#ifdef WIN32
#define APPBAR_NOTDOCKED -1
#define APPBAR_LEFT ABE_LEFT
#define APPBAR_TOP ABE_TOP
#define APPBAR_RIGHT ABE_RIGHT
#define APPBAR_BOTTOM ABE_BOTTOM
#else
#error port me
#endif
// todo : dispatch
class AppBar {
public:
virtual void appbar_dock(int side)=0;
virtual int appbar_isDocked()=0;
virtual int appbar_getSide()=0;
virtual void appbar_setEnabledSides(int mask)=0;
virtual int appbar_getEnabledSides()=0;
virtual int appbar_isSideEnabled(int side)=0;
virtual int appbar_testDock(int x, int y, RECT *dockrect=NULL)=0;
virtual int appbar_updateAutoHide()=0;
virtual int appbar_updateAlwaysOnTop()=0;
virtual int appbar_isHiding()=0;
virtual int appbar_wantAutoHide()=0;
virtual int appbar_wantAlwaysOnTop()=0;
virtual int appbar_isAutoHiding()=0;
virtual void appbar_onDock(int side) {}
virtual void appbar_onUnDock() {}
virtual void appbar_onSlide() {}
virtual void appbar_posChanged()=0;
virtual int appbar_isSideAutoHideSafe(int side)=0;
virtual int appbar_getAutoHideWidthHeight()=0;
virtual void appbar_setNoRestore(int no)=0;
};
// {242CFAA4-31B3-4b01-97C8-2F0A9FFDEF79}
static const GUID appBarGuid =
{ 0x242cfaa4, 0x31b3, 0x4b01, { 0x97, 0xc8, 0x2f, 0xa, 0x9f, 0xfd, 0xef, 0x79 } };
class api_region;
// TODO: benski> only class making active use of being derived from this seems to be Layout and GuiObjectWnd
// maybe just layout ...
class AppBarWnd : public APPBARWND_PARENT, public AppBar {
public:
AppBarWnd();
virtual ~AppBarWnd();
void appbar_dock(int side);
int appbar_isDocked();
int appbar_getSide();
void appbar_setEnabledSides(int mask);
int appbar_getEnabledSides();
int appbar_isSideEnabled(int side);
int appbar_testDock(int x, int y, RECT *dockrect=NULL);
int appbar_updateAutoHide();
int appbar_updateAlwaysOnTop();
int appbar_isSideAutoHideSafe(int side);
virtual int appbar_wantAutoHide() { return 1; }
virtual int appbar_wantAlwaysOnTop() { return 1; }
int appbar_isHiding();
int appbar_isAutoHiding();
void appbar_posChanged();
void appbar_setNoRestore(int no);
virtual int appbar_getAutoHideWidthHeight() { return 2; }
virtual LRESULT wndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
virtual void onAfterReinit();
virtual void onSetVisible(int show);
virtual void onRatioChanged();
private:
void appBarCallback(UINT uMsg, WPARAM wParam, LPARAM lParam);
int registerWinAppBar();
void unregisterWinAppBar();
void notifyWinAppBarPosition(int side, RECT rect);
OSWINDOWHANDLE getCurAutoHide(int side);
void getDockRect(int side, RECT *rc);
void getEdge(int side, RECT *rc);
void straightenRect(int side, RECT *r);
void updateDocking();
void updateSide();
void updateTimers();
void resetAutoHideSide(int side);
void setAutoHideSide(int side);
void setAutoHideTimer();
void setAutoUnHideTimer();
void resetAutoHideTimer();
void resetAutoUnHideTimer();
void onAutoHideTimer();
void onAutoUnHideTimer();
void autoHide();
void autoUnHide();
void slideWindow(RECT *prc);
int screenCorner(POINT *pt);
void snapAdjust(RECT *r, int way);
void dock(int side);
void unDock();
void unOwn();
void reOwn();
int m_registered;
int m_side;
int m_enabled;
int m_cur_autohide;
int m_cur_side;
int m_cur_hiding;
OSWINDOWHANDLE m_oldZOrder;
int m_destroying;
int m_norestore;
int m_autohide_timer_set;
int m_autounhide_timer_set;
int m_sliding;
int m_suspended;
int m_fs;
int m_wahidden;
};
#endif //_APPBARWND_H
@@ -0,0 +1,86 @@
#include <precomp.h>
#include "backbufferwnd.h"
#include <tataki/canvas/bltcanvas.h>
#include <api/api.h>
#include <tataki/region/region.h>
// -----------------------------------------------------------------------
BackBufferWnd::BackBufferWnd() {
backbuffer = 0;
canvas_w = -1;
canvas_h = -1;
back_buffer = NULL;
}
// -----------------------------------------------------------------------
BackBufferWnd::~BackBufferWnd() {
delete back_buffer;
}
//------------------------------------------------------------------------
BltCanvas *BackBufferWnd::getBackBuffer() {
return back_buffer;
}
// -----------------------------------------------------------------------
int BackBufferWnd::onPaint(Canvas *canvas) {
BBWND_PARENT::onPaint(canvas);
if (!canvas) return 1;
RECT r;
getClientRect(&r);
if (back_buffer && r.right-r.left > 0 && r.bottom -r.top > 0) {
int w = r.right-r.left;
int h = r.bottom-r.top;
if (canvas_w != w || canvas_h != h) {
delete back_buffer;
back_buffer = new BltCanvas(w, h, getOsWindowHandle());
canvas_w = w;
canvas_h = h;
}
#ifdef _WIN32
RegionI reg;
canvas->getClipRgn(&reg);
back_buffer->selectClipRgn(&reg);
#else
#warning port me
#endif
canvas->blit(r.left, r.top, back_buffer, 0, 0, w, h);
back_buffer->selectClipRgn(NULL);
}
return 1;
}
int BackBufferWnd::onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx) {
if (who_idx >= my_idx || !wantBackBuffer()) return 0;
RECT rr;
getClientRect(&rr);
api_region *_r = getRegion();
RegionI *__r=NULL;
if (!_r) {
__r = new RegionI();
_r = __r;
_r->setRect(&rr);
} else {
_r->offset(rr.left, rr.top);
}
int intersect = _r->doesIntersectRgn(r);
if (intersect)
r->addRegion(_r);
delete __r;
return intersect;
}
@@ -0,0 +1,53 @@
#ifndef __BBWND_H
#define __BBWND_H
#include <api/wnd/wndclass/abstractwndhold.h>
#ifdef WASABI_COMPILE_SKIN
#define BBWND_PARENT AbstractWndHolder
#else
#define BBWND_PARENT ServiceWndHolder
#endif
/**
class BackBufferWnd
@short
@author Nullsoft
@ver 1.0
@see
*/
class BackBufferWnd : public BBWND_PARENT {
public:
BackBufferWnd();
virtual ~BackBufferWnd();
virtual int onPaint(Canvas *c);
/**
BackBufferWnd method wantBackBuffer .
@ret 0
@param None
*/
virtual int wantBackBuffer() { return 0; }
virtual BltCanvas *getBackBuffer();
virtual int onSiblingInvalidateRgn(api_region *r, ifc_window *who, int who_idx, int my_idx);
/**
BackBufferWnd method wantSiblingInvalidations .
@ret 0
@param None
*/
virtual int wantSiblingInvalidations() { return wantBackBuffer(); }
private:
int backbuffer;
BltCanvas *back_buffer;
int canvas_w, canvas_h;
};
#endif
+24
View File
@@ -0,0 +1,24 @@
#include "precomp.h"
#include "blankwnd.h"
#include <tataki/canvas/canvas.h>
#include <api/wnd/PaintCanvas.h>
BlankWnd::BlankWnd(RGB32 _color) : color(_color)
{
}
int BlankWnd::onPaint(Canvas *canvas)
{
PaintCanvas pc;
if (canvas == NULL)
{
if (!pc.beginPaint(this)) return 0;
canvas = &pc;
}
canvas->fillRect(&clientRect(), color);
return 1;
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef _BLANKWND_H
#define _BLANKWND_H
#include <bfc/common.h>
#include <api/wnd/virtualwnd.h>
#define BLANKWND_PARENT VirtualWnd
/**
Class BlankWnd provides blank windows. The initial color can be set in the
constructor, with a default of black. There is a method for painting the window from a Canvas.
@short Blank Window with background color.
@author Nullsoft
@ver 1.0
@see VirtualWnd
*/
class BlankWnd : public BLANKWND_PARENT {
public:
/**
You can set the background color for the window via an RGB value.
The RGB value is contructed using RGB(), like so RGB(Red, Green, Blue);
@param color The RGB value of the background color to use.
*/
BlankWnd(RGB32 color=RGB(0,0,0));
/**
This event is triggered when the window needs to be repainted.
Override it to implement your own handling of this event.
@ret 1, If you handle the event;
@param canvas A pointer to the canvas on which will we paint.
*/
virtual int onPaint(Canvas *canvas);
private:
RGB32 color;
};
#endif
@@ -0,0 +1,113 @@
#include <precomp.h>
#include "bufferpaintwnd.h"
#include <tataki/canvas/bltcanvas.h>
// -----------------------------------------------------------------------
BufferPaintWnd::BufferPaintWnd() {
canvas_w = -1;
canvas_h = -1;
render_canvas = NULL;
invalidated = 1;
}
// -----------------------------------------------------------------------
BufferPaintWnd::~BufferPaintWnd() {
delete render_canvas;
}
// -----------------------------------------------------------------------
int BufferPaintWnd::onInit() {
BUFFERPAINTWND_PARENT::onInit();
return 1;
}
// -----------------------------------------------------------------------
void BufferPaintWnd::bufferPaint() {
updateCanvas();
if (render_canvas != NULL)
onBufferPaint(render_canvas, canvas_w, canvas_h);
}
void BufferPaintWnd::invalidateBuffer() {
invalidated = 1;
invalidate();
}
// -----------------------------------------------------------------------
void BufferPaintWnd::getBufferPaintSize(int *w, int *h) {
RECT r;
getClientRect(&r);
if (w) *w = r.right-r.left;
if (h) *h = r.bottom-r.top;
}
// -----------------------------------------------------------------------
void BufferPaintWnd::getBufferPaintSource(RECT *r) {
ASSERT(r != NULL);
r->left = 0;
r->right = canvas_w;
r->top = 0;
r->bottom = canvas_h;
}
// -----------------------------------------------------------------------
void BufferPaintWnd::getBufferPaintDest(RECT *r) {
ASSERT(r != NULL);
getClientRect(r);
}
// -----------------------------------------------------------------------
int BufferPaintWnd::onPaint(Canvas *canvas) {
BUFFERPAINTWND_PARENT::onPaint(canvas);
if (invalidated) bufferPaint();
invalidated = 0;
RECT r;
getBufferPaintDest(&r);
RECT sr;
getBufferPaintSource(&sr);
render_canvas->/*getSkinBitmap()->*/stretchToRectAlpha(canvas, &sr, &r, getPaintingAlpha());
return 1;
}
// -----------------------------------------------------------------------
int BufferPaintWnd::onResize() {
if (!BUFFERPAINTWND_PARENT::onResize()) return 0;
if (updateCanvas()) {
invalidated = 1;
invalidate();
}
return 1;
}
// -----------------------------------------------------------------------
int BufferPaintWnd::updateCanvas() {
int w, h;
getBufferPaintSize(&w, &h);
if (wantEvenAlignment()) {
if (w & 1) w++;
if (h & 1) h++;
}
if (w == 0 || h == 0) return 0;
int newone = 0;
if (canvas_w != w || canvas_h != h) {
if (render_canvas)
render_canvas->DestructiveResize(w, wantNegativeHeight() ? -h : h);
else
render_canvas = new BltCanvas(w, wantNegativeHeight() ? -h : h, getOsWindowHandle());
canvas_w = w;
canvas_h = h;
newone = 1;
onNewBuffer(canvas_w, canvas_h);
}
return newone;
}
@@ -0,0 +1,40 @@
#ifndef __BPAINTWND_H
#define __BPAINTWND_H
#include <api/wnd/wndclass/guiobjwnd.h>
#define BUFFERPAINTWND_PARENT GuiObjectWnd
class BufferPaintWnd : public BUFFERPAINTWND_PARENT {
public:
BufferPaintWnd();
virtual ~BufferPaintWnd();
virtual int onInit();
virtual int onPaint(Canvas *c);
virtual int onBufferPaint(BltCanvas *c, int w, int h) { return 1; }
virtual int wantEvenAlignment() { return 0; } // if you need even coordinates for your framebuffer, return 1 here
virtual void getBufferPaintSize(int *w, int *h); // by default returns client width/height
virtual void getBufferPaintSource(RECT *r); // by default returns the size of the quickpaint canvas
virtual void getBufferPaintDest(RECT *r); // by default returns the size of client area
virtual int wantNegativeHeight() { return 0; }
virtual void invalidateBuffer();
virtual int onResize();
virtual void onNewBuffer(int w, int h) {}
protected:
BltCanvas *render_canvas;
private:
void bufferPaint();
int updateCanvas();
int canvas_w, canvas_h;
int invalidated;
};
#endif
+208
View File
@@ -0,0 +1,208 @@
#include "precomp.h"
//PORTABLE
#include <bfc/wasabi_std.h>
#include <api/wnd/wndclass/buttbar.h>
#include <api/wnd/notifmsg.h>
#include <api/wnd/wndclass/buttwnd.h>
#include <api/wnd/popup.h>
#include <api/script/objects/c_script/c_text.h>
#include <api/script/objects/c_script/h_button.h>
class ButtHooker : public H_Button {
public:
ButtHooker(ButtBar *hangout, ScriptObject *butt) : bb(hangout), H_Button(butt) { }
void hook_onLeftClick() {
bb->onLeftPush(0, 0);
}
private:
ButtBar *bb;
};
ButtBar::ButtBar(int resizemode) {
spacer = 0;
resize_mode = resizemode;
hooker = NULL;
if (resize_mode == STACK) {
setContent(L"wasabi.buttonbar.stack");
}
}
ButtBar::~ButtBar() {
buttons.deleteAll();
delete hooker;
}
void ButtBar::setResizeMode(int resizemode) {
if (resize_mode == resizemode) return;
resize_mode = resizemode;
if (isPostOnInit()) onResize();
}
int ButtBar::onInit() {
int i;
BUTTBAR_PARENT::onInit();
// create the buttons
for (i = 0; i < buttons.getNumItems(); i++) {
buttons[i]->init(this);
if (resize_mode == STACK) {
if (i != 0) buttons[i]->setVisible(FALSE);
if (i == 0) setGroupLabel(buttons[i]->getButtonText());
}
}
return 1;
}
int ButtBar::addChild(ButtonWnd *child) {
buttons.addItem(child);
if (isInited()) {
child->init(this);
child->setParent(this);
onResize();
if (buttons.getNumItems() == 1)
setGroupLabel(child->getButtonText());
}
return 1;
}
int ButtBar::removeChild(ButtonWnd *child) {
if (!buttons.haveItem(child)) return 0;
if (isInited()) onResize();
return 1;
}
int ButtBar::getNumChildren() {
return buttons.getNumItems();
}
ButtonWnd *ButtBar::enumChild(int n) {
return buttons[n];
}
int ButtBar::getWidth() {
int w = 0;
for (int i = 0; i < buttons.getNumItems(); i++) {
w += buttons[i]->getWidth()+spacer;
}
return w;
}
int ButtBar::getHeight() {
if (resize_mode == STACK) {
ifc_window *rw = getContentRootWnd();
return rw->getPreferences(SUGGESTED_H);
} else {
int h = 0;
for (int i = 0; i < buttons.getNumItems(); i++) {
h = MAX(h, buttons[i]->getHeight()+1);
}
return h;
}
}
void ButtBar::onLeftPush(int x, int y)
{
if (resize_mode == STACK)
{
PopupMenu pop(this);
foreach(buttons)
pop.addCommand(buttons.getfor()->getButtonText(), foreach_index);
endfor
int r = pop.popAnchored();
if (r >= 0) {
buttons[r]->onLeftPush(0, 0);
setGroupLabel(buttons[r]->getButtonText());
}
}
}
int ButtBar::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2) {
switch (msg) {
case ChildNotify::BUTTON_LEFTPUSH: {
int ret;
if (ret = onLeftPush(child->getNotifyId())) {
return ret;
} else {
// This won't fit the current notification schema.
// We _must_ change it -- too many interfaces assume that the
// button notification is called back through the parent.
// return notifyParent(msg, p1, p2);
// So, I made a new basewnd method passNotifyUp() to defer a notification
// to the current object's notification target.
return passNotifyUp(child, msg, p1, p2);
}
}
break;
}
return BUTTBAR_PARENT::childNotify(child, msg, p1, p2);
}
int ButtBar::onResize() {
BUTTBAR_PARENT::onResize(); // calling your parent is good(tm) =)
if (!isPostOnInit()) return 0; // that's just an optim, in case someone's dumb and calling us directly when it shouldnt
switch (resize_mode) {
case NORMAL: {
RECT r = clientRect();
int height = r.bottom - r.top;
int x = r.left;
for (int i = 0; i < buttons.getNumItems(); i++) {
int w = buttons[i]->getWidth()+spacer;
buttons[i]->resize(x, r.top, w, height);
x += w;
if (x > r.right) break;
}
}
break;
case STRETCH: {
if (buttons.getNumItems() > 0) {
RECT r = clientRect();
int height = r.bottom - r.top;
int w = (r.right - r.left) / buttons.getNumItems();
int x = r.left;
for (int i = 0; i < buttons.getNumItems(); i++) {
if (i == buttons.getNumItems()-1) w = (r.right - r.left) - x;
buttons[i]->resize(x, r.top, w, height);
x += w;
}
}
}
break;
case STACK: // no point
break;
}
return 1;
}
int ButtBar::onPaint(Canvas *canvas) {
ASSERT(canvas != NULL);
if (resize_mode != STACK) {
BUTTBAR_PARENT::onPaint(canvas);
renderBaseTexture(canvas, clientRect());
}
return 1;
}
void ButtBar::setGroupLabel(const wchar_t *l) {
setName(l);
onNewContent();
}
void ButtBar::onNewContent()
{
if (resize_mode != STACK) return;
ScriptObject *text = findScriptObject(L"buttonbar.text");
if (text == NULL) return;
C_Text(text).setText(getNameSafe(L"no tabs"));
// hook the clicks
delete hooker;
ScriptObject *mousetrap = findScriptObject(L"mousetrap");
hooker = new ButtHooker(this, mousetrap);
}
+168
View File
@@ -0,0 +1,168 @@
#ifndef _BUTTBAR_H
#define _BUTTBAR_H
#include <bfc/common.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <bfc/ptrlist.h>
class ButtonWnd;
class ButtHooker;
#define BUTTBAR_PARENT GuiObjectWnd
/**
A resizable button bar control.
@short A resizable button bar
@author Nullsoft
@ver 1.0
@see ButtonWnd
*/
class ButtBar : public BUTTBAR_PARENT {
public:
// resize modes
/**
Resize modes for the button bar.
*/
enum { NORMAL, STRETCH, STACK };
/**
You can set the resize mode for the button bar by specifying it
via the contructor.
@see ~ButtBar() setResizeMode()
@param resizemode The default resize mode.
*/
ButtBar(int resizemode=NORMAL);
/**
Deletes all the buttons present in the button bar.
@see ButtBar()
*/
virtual ~ButtBar();
/**
This event is triggered when the button bar is being initialized.
If you override this, please call up the parent chain first, then
do your initialization.
@ret 1
*/
virtual int onInit();
/**
This event is triggered when the button bar is being resized.
If you override this, please call up the parent chain first, then
do your own resize handling.
@ret 1
*/
virtual int onResize();
/**
This event is triggered when the button bar is being painted.
If you override this, please call up the parent chain first, then
do your painting.
@ret 1
@param canvas The canvas upon which we will paint ourself.
*/
virtual int onPaint(Canvas *canvas);
/**
Sets the resize mode for the button bar.
@param resizemode NORMAL, Normal Resize; STRETCH, Stretch the button bar to window width; STACK, ?;
*/
virtual void setResizeMode(int resizemode);
/**
Enables you to add a child window to your button bar.
Since this is a button bar, the windows you can add must be
derived or be ButtonWnd's.
@see removeChild()
@see getNumChildren()
@see enumChild()
@see ButtonWnd
@ret 1
@param child A pointer to the child window to add.
*/
int addChild(ButtonWnd *child);
/**
*/
int removeChild(ButtonWnd *child); // does not delete, just removes
/**
Get the number of children (buttons) that the button bar has.
@ret The number of children (buttons).
*/
int getNumChildren();
/**
Get a pointer to a child (button) in the button bar, by button index number.
The first button added is at index 0.
@ret !NULL, a pointer the requested button; NULL, The button does not exist;
*/
ButtonWnd *enumChild(int n);
/**
Get the width of the button bar (in pixels).
@see getHeight()
@ret Width of the button bar (in pixels).
*/
int getWidth();
/**
Get the height of the button bar (in pixels).
@see getWidth()
@ret Height of the button bar (in pixels).
*/
int getHeight();
/**
Event is triggered when the left mouse button is used to click on the
button bar. Override this to implement your own handling of the event.
If you override this method, call up the parent chain.
@param x The x coordinate of the mouse cursor in the button bar.
@param y The y coordinate of the mouse cursor in the button bar.
*/
virtual void onLeftPush(int x, int y);
/**
Notify a child window via a generic message system.
@see addChild()
@ret
@param child A pointer to the child window which will receive the notify.
@param msg The message you want to send to the child.
@param p1 A user parameter.
@param p2 A user parameter.
*/
virtual int childNotify(ifc_window *child, int msg,
intptr_t param1=0, intptr_t param2=0);
// GuiObjectWnd
virtual void onNewContent();
void setSpacer(int sp) { spacer = sp; }
void setGroupLabel(const wchar_t *l);
protected:
virtual int onLeftPush(int id) { return 0; }
PtrList<ButtonWnd> buttons;
private:
int resize_mode;
int spacer;
ButtHooker *hooker;
};
#endif
+761
View File
@@ -0,0 +1,761 @@
#include <precomp.h>
// bitmap-style buttons
#include "buttwnd.h"
#include <bfc/wasabi_std.h>
#include <tataki/canvas/bltcanvas.h>
#include <tataki/region/region.h>
#include <api/wnd/notifmsg.h>
#include <api/wndmgr/msgbox.h>
#include <api/wnd/PaintCanvas.h>
#define DEFAULT_BUTTON_HEIGHT 20
ButtonWnd::ButtonWnd(const wchar_t *button_text)
{
if (button_text != NULL)
setName(button_text);
currgn = NULL;
hirgn = NULL;
normalrgn = NULL;
pushedrgn = NULL;
activatedrgn = NULL;
base_texture = NULL;
xShift=0;
yShift=0;
textsize = DEFAULT_BUTTON_TEXT_SIZE;
alignment = TEXTALIGN_CENTER;
activated = 0;
userhilite = 0;
userdown = 0;
use_base_texture = 0;
center_bitmap = 0;
enabled = 1;
checked=0;
autodim=0;
borders = 1;
borderstyle = 0;
setBorderStyle(L"button_normal");
iwantfocus = 1;
color_text = L"wasabi.button.text";
color_hilite = L"wasabi.button.hiliteText";
color_dimmed = L"wasabi.button.dimmedText";
checkbmp = L"wasabi.popup.menu.check";
inactivealpha = 255;
activealpha = 255;
setRectRgn(1);
retcode = MSGBOX_ABORTED;
forcedown=0;
}
ButtonWnd::~ButtonWnd() {
delete normalrgn;
delete pushedrgn;
delete hirgn;
delete activatedrgn;
}
void ButtonWnd::checkState(POINT *pt) {
POINT pt2;
if (pt == NULL) {
pt = &pt2;
Wasabi::Std::getMousePos(pt);
}
api_region *old = currgn;
if (getDown()) { // button is down
if (pushedrgn)
currgn = pushedrgn;
else
currgn = normalrgn;
} else { // button is not down
if (hirgn && getHilite())
currgn = hirgn;
else
currgn = normalrgn;
}
if (old != currgn) invalidateWindowRegion();
}
void ButtonWnd::onCancelCapture() {
BUTTONWND_PARENT::onCancelCapture();
checkState();
}
int ButtonWnd::onMouseMove(int x, int y) {
POINT pt;
checkState(&pt);
return BUTTONWND_PARENT::onMouseMove(x, y);
}
api_region *ButtonWnd::getRegion() {
if (borders) return NULL;
return currgn;
}
void ButtonWnd::setModalRetCode(int r) { retcode = r; }
int ButtonWnd::getModalRetCode() const { return retcode; }
void ButtonWnd::onLeaveArea() {
BUTTONWND_PARENT::onLeaveArea();
if (hirgn || getDown()) invalidate();
}
void ButtonWnd::onEnterArea() {
BUTTONWND_PARENT::onEnterArea();
if (hirgn) invalidate();
}
/*BOOL ButtonWnd::mouseInRegion(int x, int y) {
POINT pos={x,y};
POINT p2=pos;
RECT r;
getClientRect(&r);
pos.x-=r.left;
pos.y-=r.top;
return (((!currgn || rectrgn) && PtInRect(&r, p2)) || (currgn && currgn->ptInRegion(&pos)));
}*/
int ButtonWnd::setBitmaps(const wchar_t *_normal, const wchar_t *_pushed, const wchar_t *_hilited, const wchar_t *_activated) {
if (_normal) { delete normalrgn; normalrgn = NULL; }
if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
if (_hilited) { delete hirgn; hirgn = NULL; }
if (_activated) { delete activatedrgn; activatedrgn = NULL; }
if (_normal) {
normalbmp = _normal;
normalrgn = new RegionI(normalbmp.getBitmap());
currgn = normalrgn;
}
if (_pushed) {
pushedbmp = _pushed;
pushedrgn = new RegionI(pushedbmp.getBitmap());
}
if (_hilited) {
hilitebmp = _hilited;
hirgn = new RegionI(hilitebmp.getBitmap());
}
if (_activated) {
activatedbmp = _activated;
activatedrgn = new RegionI(activatedbmp.getBitmap());
}
if (isPostOnInit())
invalidate();
return 1;
}
SkinBitmap *ButtonWnd::getNormalBitmap() {
return normalbmp.getBitmap();
}
void ButtonWnd::freeResources() {
BUTTONWND_PARENT::freeResources();
delete normalrgn;
delete pushedrgn;
delete hirgn;
delete activatedrgn;
pushedrgn=NULL;
normalrgn=NULL;
hirgn=NULL;
activatedrgn=NULL;
currgn=NULL;
}
void ButtonWnd::reloadResources() {
BUTTONWND_PARENT::reloadResources();
if (normalbmp.getBitmap())
normalrgn = new RegionI(normalbmp.getBitmap());
if (pushedbmp.getBitmap())
pushedrgn = new RegionI(pushedbmp.getBitmap());
if (hilitebmp.getBitmap())
hirgn = new RegionI(hilitebmp.getBitmap());
if (activatedbmp.getBitmap())
activatedrgn = new RegionI(activatedbmp.getBitmap());
currgn = normalrgn;
}
int ButtonWnd::setBitmapCenter(int centerit) {
return center_bitmap = !!centerit;
}
int ButtonWnd::setBitmaps(OSMODULEHANDLE hInst, int _normal, int _pushed, int _hilited, int _activated, const wchar_t *_colorgroup)
{
if (_normal) { delete normalrgn; normalrgn = NULL; }
if (_pushed) { delete pushedrgn; pushedrgn = NULL; }
if (_hilited) { delete hirgn; hirgn = NULL; }
if (_activated) { delete activatedrgn; activatedrgn = NULL; }
if (_colorgroup == NULL)
_colorgroup = colorgroup;
if (_normal)
{
normalbmp.setHInstanceBitmapColorGroup(_colorgroup);
#ifdef _WIN32
normalbmp.setHInstance(hInst);
#else
#warning port me?
#endif
normalbmp = _normal;
normalrgn = new RegionI(normalbmp.getBitmap());
}
if (_pushed) {
pushedbmp.setHInstanceBitmapColorGroup(_colorgroup);
#ifdef _WIN32
pushedbmp.setHInstance(hInst);
#else
#warning port me?
#endif
pushedbmp = _pushed;
pushedrgn = new RegionI(pushedbmp.getBitmap());
}
if (_hilited) {
hilitebmp.setHInstanceBitmapColorGroup(_colorgroup);
#ifdef _WIN32
hilitebmp.setHInstance(hInst);
#else
#warning port me?
#endif
hilitebmp = _hilited;
hirgn = new RegionI(hilitebmp.getBitmap());
}
if (_activated) {
activatedbmp.setHInstanceBitmapColorGroup(_colorgroup);
#ifdef _WIN32
activatedbmp.setHInstance(hInst);
#else
#warning port me?
#endif
activatedbmp = _activated;
activatedrgn = new RegionI(activatedbmp.getBitmap());
}
return 1;
}
void ButtonWnd::setUseBaseTexture(int useit)
{
if (use_base_texture == useit) return;
use_base_texture = useit;
invalidate();
}
void ButtonWnd::setBaseTexture(SkinBitmap *bmp, int x, int y, int tile)
{
base_texture = bmp;
use_base_texture = TRUE;
tile_base_texture=tile;
xShift=x;
yShift=y;
invalidate();
}
int ButtonWnd::setButtonText(const wchar_t *text, int size)
{
textsize = size;
ASSERT(textsize > 0);
setName(text);
invalidate();
return 1;
}
const wchar_t * ButtonWnd::getButtonText()
{
return getName();
}
void ButtonWnd::setTextAlign(TextAlign align)
{
alignment = align;
invalidate();
}
int ButtonWnd::getWidth()
{
int addl=0;
if (checked) {
addl=checkbmp.getWidth()+3;
}
if (rightbmp.getBitmap())
addl+=rightbmp.getWidth()+3;
if (normalbmp == NULL)
{
TextInfoCanvas blt(this);
Wasabi::FontInfo fontInfo;
fontInfo.pointSize = textsize;
StringPrintfW lstr(L"j%sj", getNameSafe(L""));
if (wcschr(lstr, '\t')) lstr.cat(L" ");
int a=MAX((blt.getTextWidth(lstr, &fontInfo)*11)/10,8)+addl;
return a;
}
return normalbmp.getWidth()+addl;
}
int ButtonWnd::getHeight()
{
int minh=0;
if (checked>0)
minh=checkbmp.getHeight();
if (rightbmp.getBitmap())
minh=MAX(rightbmp.getHeight(),minh);
if (normalbmp == NULL)
{
TextInfoCanvas blt(this);
Wasabi::FontInfo fontInfo;
fontInfo.pointSize = textsize;
int r = MAX(MAX((blt.getTextHeight(getName(), &fontInfo)*11)/10,minh),4);
return r;
}
return MAX(normalbmp.getHeight(),minh);
}
void ButtonWnd::enableButton(int _enabled) {
_enabled = !!_enabled;
if (enabled != _enabled) invalidate();
enabled = _enabled;
onEnable(enabled);
}
int ButtonWnd::getEnabled() const {
return enabled;
}
int ButtonWnd::onPaint(Canvas *canvas)
{
PaintBltCanvas paintcanvas;
SkinBitmap *bmp;
RECT r;
int labelxoffs=0;
int offset = (enabled&&(getPushed()||getDown())) ? 1 : 0;
if (checked) labelxoffs+=3+checkbmp.getWidth();
if (canvas == NULL) {
if (!paintcanvas.beginPaint(this)) return 0;
canvas = &paintcanvas;
}
BUTTONWND_PARENT::onPaint(canvas);
bmp = normalbmp;
if (pushedbmp && (getDown() || getPushed())) bmp = pushedbmp;
else if ((getHilite() || userhilite) && hilitebmp) bmp = hilitebmp;
else if (activatedbmp && getActivatedButton()) bmp = activatedbmp;
getClientRect(&r);
RECT nr = r;
// RECT fcr = r;
if (use_base_texture)
{
if (!base_texture)
renderBaseTexture(canvas, r);
else {
RECT cr;
cr.left = xShift;
cr.top = yShift;
cr.right = cr.left + (r.right-r.left);
cr.bottom = cr.top + (r.bottom-r.top);
if (tile_base_texture) base_texture->blitTile(canvas, &r,xShift,yShift);
else base_texture->stretchToRectAlpha(canvas, &cr, &r, getPaintingAlpha());
}
}
else
{
if (borders)
{
int sysobj = -1;
if (!enabled)
sysobj = dsoDisabled;
else
sysobj = (getPushed() || getDown()) ? dsoPushed : dsoNormal;
if (sysobj != -1) canvas->drawSysObject(&nr, sysobj, getPaintingAlpha());
}
}
if (checked>0)
{
RECT ar;
int c=(r.top+r.bottom)/2;
ar.left=r.left;
ar.top=c-checkbmp.getHeight()/2;
ar.bottom=ar.top+checkbmp.getHeight();
ar.right=r.left+checkbmp.getWidth();
checkbmp.getBitmap()->stretchToRectAlpha(canvas,&ar,getPaintingAlpha());
}
if (rightbmp.getBitmap()) {
RECT ar;
int c=(r.top+r.bottom)/2;
ar.top=c-rightbmp.getHeight()/2;
ar.bottom=ar.top+rightbmp.getHeight();
ar.right=r.right;
ar.left=ar.right-rightbmp.getWidth();
int alpha = getPaintingAlpha();
if (!getEnabled()) alpha /= 2;
rightbmp.getBitmap()->stretchToRectAlpha(canvas, &ar, alpha);
}
if (bmp != NULL) {
RECT br = r;
if (center_bitmap) {
int w = (r.right - r.left) - getWidth() - labelxoffs;
int h = (r.bottom - r.top) - getHeight();
br.top = r.top + h/2 + offset;
br.bottom = br.top + getHeight();
br.left = r.left + w/2 + labelxoffs + offset;
br.right = br.left + getWidth() - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
} else {
br.left += labelxoffs;
br.right -= (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
}
int alpha2;
if (!hilitebmp && enabled && autodim) {
alpha2=128;
if (getHilite() || userhilite) alpha2=255;
} else alpha2 = enabled ? 255 : 64;
bmp->stretchToRectAlpha(canvas, &br,autodim ? (getPaintingAlpha()+alpha2)>>1 : getPaintingAlpha());
}
if (getName() != NULL)
{
Wasabi::FontInfo fontInfo;
fontInfo.opaque = false;
fontInfo.pointSize = textsize;;
int textw, texth;
canvas->getTextExtent(getName(), &textw, &texth, &fontInfo);
if (!enabled)
fontInfo.color = color_dimmed;
else if (userhilite)
fontInfo.color = color_hilite;
else
fontInfo.color = color_text;
int h=(r.bottom-r.top-texth)/2;
if (h<0) h=0;
r.left += offset + labelxoffs;
r.right += offset - (rightbmp.getBitmap()?rightbmp.getWidth()+3:0);
r.top += offset+h;
r.bottom = r.top+texth;
switch (alignment)
{
case TEXTALIGN_CENTER:
canvas->textOutCentered(&r, getName(), &fontInfo);
break;
case TEXTALIGN_RIGHT:
canvas->textOut(r.right-textw, r.top, textw, texth, getName(), &fontInfo);
break;
case TEXTALIGN_LEFT:
if (!wcsstr(getName(), L"\t"))
{
canvas->textOut(r.left, r.top, r.right-r.left, r.bottom-r.top, getName(), &fontInfo);
}
else
{
StringW lstr(getName());
wchar_t *p=wcsstr(lstr.getNonConstVal(),L"\t");
if (p) *p++=0;
else p=L"";
int tw=canvas->getTextWidth(p, &fontInfo);
canvas->textOut(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr, &fontInfo);
canvas->textOut(r.right-tw, r.top, tw, r.bottom-r.top, p, &fontInfo);
}
break;
case TEXTALIGN_LEFT_ELLIPSIS:
if (!wcsstr(getName(),L"\t"))
{
canvas->textOutEllipsed(r.left, r.top, r.right-r.left, r.bottom-r.top, getName(), &fontInfo);
}
else
{
StringW lstr(getName());
wchar_t *p=wcsstr(lstr.getNonConstVal(),L"\t");
if (p) *p++=0;
else p=L"";
int tw=canvas->getTextWidth(p, &fontInfo);
canvas->textOutEllipsed(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr, &fontInfo);
canvas->textOutEllipsed(r.right-tw, r.top, tw, r.bottom-r.top, p, &fontInfo);
}
break;
}
/*
if (textjustify == BUTTONJUSTIFY_CENTER)
canvas->textOutCentered(&r, getName());
else if (textjustify == BUTTONJUSTIFY_LEFT)
{
if (!STRSTR(getName(),"\t"))
canvas->textOutEllipsed(r.left, r.top, r.right-r.left, r.bottom-r.top, getName());
else
{
char *lstr=STRDUP(getName());
char *p=STRSTR(lstr,"\t");
if (p) *p++=0;
else p="";
int tw=canvas->getTextWidth(p);
canvas->textOutEllipsed(r.left, r.top, r.right-r.left-tw, r.bottom-r.top, lstr);
canvas->textOutEllipsed(r.right-tw, r.top, tw, r.bottom-r.top, p);
FREE(lstr);
}
}
*/
}
/* if (enabled && gotFocus() && wantFocus()) { // SKIN ME
fcr.left+=3;
fcr.right-=3;
fcr.top+=3;
fcr.bottom-=3;
DrawFocusRect(canvas->getHDC(), &fcr);
}*/
return 1;
}
void ButtonWnd::onLeftPush(int x, int y)
{
notifyParent(ChildNotify::BUTTON_LEFTPUSH);
invalidate();
}
void ButtonWnd::onRightPush(int x, int y) {
notifyParent(ChildNotify::BUTTON_RIGHTPUSH);
invalidate();
}
void ButtonWnd::onLeftDoubleClick(int x, int y) {
notifyParent(ChildNotify::BUTTON_LEFTDOUBLECLICK);
}
void ButtonWnd::onRightDoubleClick(int x, int y) {
notifyParent(ChildNotify::BUTTON_RIGHTDOUBLECLICK);
}
void ButtonWnd::setHilite(int h) {
h = !!h;
if (userhilite != h) {
userhilite = h;
invalidate();
}
}
int ButtonWnd::getHilite() {
return userhilite || BUTTONWND_PARENT::getHilite();
}
int ButtonWnd::getPushed() const {
return userdown || forcedown;
}
void ButtonWnd::setPushed(int p) {
p = !!p;
if (userdown != p)
{
userdown=p;
invalidate();
}
}
int ButtonWnd::onResize() {
BUTTONWND_PARENT::onResize();
// invalidate();
return 1;
}
void ButtonWnd::setCheckBitmap(const wchar_t *checkbm) {
checkbmp = checkbm;
}
int ButtonWnd::setRightBitmap(const wchar_t *bitmap) {
rightbmp=bitmap;
return 1;
}
void ButtonWnd::setActivatedButton(int a) {
if (activated != a) {
activated = a;
invalidate();
onActivateButton(activated);
}
}
void ButtonWnd::setActivatedNoCallback(int a) {
// also force invalidate.
activated = a;
invalidate();
}
int ButtonWnd::onActivateButton(int active) {
return 1;
}
int ButtonWnd::getActivatedButton() {
return activated;
}
void ButtonWnd::setBorders(int b) {
b = !!b;
if (borders != b) {
borders = b;
setRectRgn(borders);
invalidate();
}
}
void ButtonWnd::setBorderStyle(const wchar_t *style) {
if (style == NULL) style = L"";
if (borderstyle && !WCSICMP(borderstyle, style)) return;
// borderstyle = style;
using namespace DrawSysObj;
static struct {
const wchar_t *style;
int normal, pushed, disabled;
} chart[] = {
{ L"button_normal", BUTTON, BUTTON_PUSHED, BUTTON_DISABLED },
{ L"osbutton_normal", OSBUTTON, OSBUTTON_PUSHED, OSBUTTON_DISABLED },
{ L"osbutton_close", OSBUTTON_CLOSE, OSBUTTON_CLOSE_PUSHED, OSBUTTON_CLOSE_DISABLED },
{ L"osbutton_minimize", OSBUTTON_MINIMIZE, OSBUTTON_MINIMIZE_PUSHED, OSBUTTON_MINIMIZE_DISABLED },
{ L"osbutton_maximize", OSBUTTON_MAXIMIZE, OSBUTTON_MAXIMIZE_PUSHED, OSBUTTON_MAXIMIZE_DISABLED },
{ NULL, BUTTON, BUTTON_PUSHED, BUTTON_DISABLED },
};
dsoNormal = dsoPushed = dsoDisabled = -1;
for (int i = 0; ; i++) {
if (chart[i].style == NULL) return;
if (!WCSICMP(chart[i].style, style)) {
borderstyle = chart[i].style;
dsoNormal = chart[i].normal;
dsoPushed = chart[i].pushed;
dsoDisabled = chart[i].disabled;
}
}
invalidate();
}
const wchar_t *ButtonWnd::getBorderStyle() {
return borderstyle;
}
void ButtonWnd::setInactiveAlpha(int a) {
inactivealpha=a;
}
void ButtonWnd::setActiveAlpha(int a) {
activealpha=a;
}
int ButtonWnd::onGetFocus() {
BUTTONWND_PARENT::onGetFocus();
// invalidate();
return 1;
}
int ButtonWnd::onKillFocus() {
BUTTONWND_PARENT::onKillFocus();
// invalidate();
return 1;
}
void ButtonWnd::setColors(const wchar_t *text, const wchar_t *hilite, const wchar_t *dimmed) {
color_text=text;
color_hilite=hilite;
color_dimmed=dimmed;
invalidate();
}
void ButtonWnd::setTextColor(const wchar_t *text) {
color_text=text;
invalidate();
}
void ButtonWnd::setTextHoverColor(const wchar_t *hilite) {
color_hilite=hilite;
invalidate();
}
void ButtonWnd::setTextDimmedColor(const wchar_t *dimmed) {
color_dimmed=dimmed;
invalidate();
}
int ButtonWnd::onEnable(int is) {
return BUTTONWND_PARENT::onEnable(is);
}
int ButtonWnd::getPreferences(int what) {
switch (what) {
case SUGGESTED_W: {
if (!normalBmpStr.isempty()) return normalbmp.getWidth();
return getWidth();
}
case SUGGESTED_H: {
if (!normalBmpStr.isempty()) return normalbmp.getHeight();
return getHeight();
}
}
return BUTTONWND_PARENT::getPreferences(what);
}
int ButtonWnd::onInit() {
int r = BUTTONWND_PARENT::onInit();
currgn = normalrgn;
return r;
}
int ButtonWnd::onChar(unsigned int c)
{
switch (c) {
#ifdef _WIN32
case VK_RETURN:
case VK_SPACE:
postDeferredCallback(DEFEREDCB_DOWN, 0, 0);
postDeferredCallback(DEFEREDCB_UP, 0, 250);
//return BUTTONWND_PARENT::onChar(c);
break;
#else
#warning port me
#endif
default:
return BUTTONWND_PARENT::onChar(c);
}
return 1;
}
int ButtonWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
switch (p1) {
case DEFEREDCB_DOWN:
forcedown = 1;
invalidate();
break;
case DEFEREDCB_UP:
forcedown = 0;
invalidate();
RECT r;
getClientRect(&r);
onLeftPush(r.left+(r.right-r.left)/2, r.top+(r.bottom-r.top)/2);
default:
return BUTTONWND_PARENT::onDeferredCallback(p1, p2);
}
return 1;
}
+602
View File
@@ -0,0 +1,602 @@
#ifndef _BUTTWND_H
#define _BUTTWND_H
#include <wasabicfg.h>
#include <bfc/common.h>
#include <tataki/canvas/canvas.h>
#include <tataki/bitmap/autobitmap.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <tataki/color/skinclr.h>
#include <api/wnd/accessible.h>
#include <api/wnd/textalign.h>
class api_region;
#define DEFAULT_BUTTON_TEXT_SIZE 14
/**
Button Text Alignment
Darkain: this was changed to use TextAlign
*/
/*
typedef enum {
BUTTONJUSTIFY_LEFT,
BUTTONJUSTIFY_CENTER
} ButtonJustify;
*/
#define DEFEREDCB_DOWN 0x450
#define DEFEREDCB_UP 0x451
#define BUTTONWND_PARENT GuiObjectWnd
/**
A fully skinnable button. Has images for normal, hilited, activated states.
Plus images for a checked state. It may also be used to draw OS style buttons.
See setBorderStyle() for more details.
@short Button control.
@author Nullsoft
@ver 1.0
@see ButtBar
*/
class ButtonWnd : public BUTTONWND_PARENT {
public:
/**
Sets defaults for ButtonWnd objects.
@see ~ButtonWnd()
@param button_text The button's caption.
*/
ButtonWnd(const wchar_t *button_text=NULL);
/**
Deletes components of ButtonWnd.
@see ButtonWnd()
*/
virtual ~ButtonWnd();
/**
Paints the bitmap on canvas according
to current options (centering, tiling, stretching, title).
@ret 0 for failure, 1 for success
@param canvas The canvas on which to paint.
*/
virtual int onPaint(Canvas *canvas);
/**
Sets the bitmaps that will be used to render the button.
This includes bitmaps for various button states. Also enables
you to set the colorgroup (gammagroup) for the bitmaps.
@ret 1
@param _normal Bitmap for normal state.
@param _pushed Bitmap for pushed state.
@param _hilited Bitmap for hilited state.
@param _activated Bitmap for activated state.
@param colorgroup The colorgroup for the bitmaps (gammagroup).
*/
int setBitmaps(const wchar_t *normal, const wchar_t *pushed=NULL, const wchar_t *hilited=NULL, const wchar_t *activated=NULL);
SkinBitmap *getNormalBitmap();
/**
Sets the bitmaps that will be used to render the button.
This includes bitmaps for various button states. Also enables
you to set the colorgroup (gammagroup) for the bitmaps.
@ret 1
@param hInst The parent window's instance handle.
@param _normal Bitmap for normal state.
@param _pushed Bitmap for pushed state.
@param _hilited Bitmap for hilited state.
@param _activated Bitmap for activated state.
@param colorgroup The colorgroup for the bitmaps (gammagroup).
*/
int setBitmaps(OSMODULEHANDLE hInst, int normal, int pushed, int hilited, int activated, const wchar_t *colorgroup=NULL);
/**
Set the right bitmap to be used.
@see setBitmaps()
@ret 1
@param bitmap The name of the bitmap to use.
*/
int setRightBitmap(const wchar_t *bitmap);
/**
Center the bitmap?
@see setBitmaps()
@ret Normalized flag
@param centerit A non zero value will center the bitmap.
*/
int setBitmapCenter(int centerit);
/**
Sets base texture and causes rerendering.
@see setBaseTexture()
@param useit A non zero value will use the base texture.
*/
void setUseBaseTexture(int useit);
/**
Sets bitmap for button, sets position for button, flags whether to tile the bitmap
@see setUseBaseTexture()
@param bmp Skin bitmap for button
@param x Button position on x-coordinate
@param yButton position on y-coordinate
@param tile Flag
*/
void setBaseTexture(SkinBitmap *bmp, int x, int y, int tile=0);
/**
Sets the colorgroup (gammagroup) for all the bitmaps associated with
this button.
@param _colorgroup The colorgroup for the bitmaps.
*/
void setHInstanceColorGroup(const wchar_t *_colorgroup) { colorgroup = _colorgroup; }
/**
Writes given text to button in given size and triggers rendering.
@see getButtonText()
@assert Text string is not empty
@ret 1
@param text Label text
@param size Size to render label text
*/
int setButtonText(const wchar_t *text, int size=DEFAULT_BUTTON_TEXT_SIZE);
/**
Gets text from button.
@see setButtonText()
@ret Button text string
*/
const wchar_t * getButtonText();
/**
Sets text to render at left, in center, or at right.
@see setButtonText()
@see getButtonText()
@see ButtonJustify
@param jus BUTTONJUSTIFY_LEFT, left justified; BUTTONJUSTIFY_CENTER, centered;
*/
// void setTextJustification(ButtonJustify jus);
void setTextAlign(TextAlign align);
TextAlign getTextAlign() { return alignment; }
/**
Enables and disables wantfocus for the button. When disabled, the button can
never receive focus.
@param want !0, enable focus; 0, disable focus;
*/
void setWantFocus(int want) { iwantfocus = !!want; }
/**
Return the wantfocus
*/
virtual int wantFocus() const { return iwantfocus; }
/**
Event is triggered when the mouse leaves the button's region.
Override this event to implement your own behavior.
*/
virtual void onLeaveArea();
virtual void onEnterArea();
/**
Gets width of button, allowing for length of text plus button margin, if any.
@see getHeight()
@ret Button width (in pixels).
*/
int getWidth(); // our preferred width and height (from bitmaps)
/**
Gets height of button, allowing for height of text plus button margin, if any.
@see getWidth()
@ret Button height (in pixels).
*/
int getHeight();
/**
Event is triggered when focus is given to the button.
Override this event to implement your own behavior.
@see onKillFocus()
@ret 1
*/
virtual int onGetFocus();
/**
Event is triggered when the button focus is lost.
Override this event to implement your own behavior.
@see onGetFocus()
@ret 1
*/
virtual int onKillFocus();
/**
Event is triggered when a key is pressed and the button
has focus.
@ret 1, if you handle the event;
@param c The value of the key that was pressed.
*/
virtual int onChar(unsigned int c);
/**
Saves new status and rerenders, if button enabled status changes.
@see getEnabled()
@see onEnable()
@param _enabled 0, disabled; !0 enabled;
*/
void enableButton(int enabled); // can be pushed
/**
Tells parent to handle left button click.
@see onRightPush()
@param x Mouse click x-coordinate
@param y Mouse click y-coordinate
*/
virtual void onLeftPush(int x, int y);
/**
Passes right mouse clicks to the parent.
@see onLeftPush()
@param x Mouse click x-coordinate
@param y Mouse click y-coordinate
*/
virtual void onRightPush(int x, int y);
/**
Passes left double click to parent.
@see onRightDoubleClick()
@param x Mouse click x-coordinate
@param y Mouse click y-coordinate
*/
virtual void onLeftDoubleClick(int x, int y);
/**
Passes right double click to parent
@see onLeftDoubleClick()
@param x Mouse click x-coordinate
@param y Mouse click y-coordinate
*/
virtual void onRightDoubleClick(int x, int y);
/**
Event is triggered when the button will be resized.
Override this event to implement your own behavior.
The default behavior is to cause a repaint.
@ret 1
*/
virtual int onResize();
/**
Sets the region pointed at after each mouse move.
If the region has changed, it invalidate the region
so that it will be updated on the screen.
@ret Status from parent class
@param x New x-coordinate of mouse cursor
@param y New y-coordinate of mouse cursor
*/
virtual int onMouseMove(int x, int y); // need to catch region changes
/**
Event is triggered when the button is enabled or disabled.
Override this event to implement your own behavior.
@see getEnabled()
@ret 1
@param is The enable state (nonzero is enabled).
*/
virtual int onEnable(int is);
/**
Returns the value of the enabled flag.
@see enableButton()
@see onEnable()
@ret enabled
*/
virtual int getEnabled() const;
/**
Get the preferences for this button.
This will enable you to read the suggested width and height
for the button.
@ret Width or height of the normal bitmap, as requested, or a property from the parent class.
@param what SUGGESTED_W, will return the width; SUGGESTED_H, will return the height;
*/
virtual int getPreferences(int what);
/**
Get the button state. This is the state caused by user interaction.
@ret !0, pushed; 0, not pushed;
*/
virtual int userDown() { return userdown; }
/**
*/
virtual int wantClicks() { return getEnabled(); }
/**
Set the bitmap to use when the button will be "checked".
This enables you to have checked buttons and menu items.
@see setChecked()
@see getChecked()
@param checkbm The name of the bitmap to use.
*/
void setCheckBitmap(const wchar_t *checkbm);
/**
Set the checked state of the button.
@param c <0, not checked; 0, none, >0 checked;
*/
void setChecked(int c) { checked=c; }; // <0=nocheck, 0=none, >0=checked
/**
Get the checked state of the button.
@ret <0, not checked; 0, none; >0 checked;
*/
int getChecked() const { return checked; }
/**
Triggers rerendering in the opposite
highlight state if the hilighting flag is changed.
@see getHilite()
@param h
*/
void setHilite(int h);
/**
@see setHilite()
@ret Is either highlighting flag set?
*/
int getHilite();
/**
Simulate a button push. You can use this method to simulate
menu pushing also.
@see getPushed()
@param p A nonzero value will simulate a push.
*/
void setPushed(int p); // used by menus to simulate pushing
/**
Get the pushed state of a button.
@see setPushed()
@ret 0, not pushed; !0, pushed;
*/
int getPushed() const; // used by menus to simulate pushing
/**
Sets the auto dim state. Autodim will dim the normal
bitmap if no hilite bitmap is provided.
@param ad !0, autodim on; 0, autodim off;
*/
void setAutoDim(int ad) { autodim=!!ad; } // nonzero makes it dim if there's no hilite bitmap
/**
Get the autodim state.
@see setAutoDim()
@ret 0, autodim off; !0 autodim on;
*/
int getAutoDim() const { return autodim; } // nonzero makes it dim if there's no hilite bitmap
/**
Set the active state of the button.
@see getActivatedButton()
@see setActivatedNoCallback()
@param a !0, activate the button; 0, deactivate the button;
*/
virtual void setActivatedButton(int a);
/**
Set the active state of the button, without generating a callback.
This means that the onActivated event will not fire for this button.
@see getActivatedButton()
@see setActivatedButton()
@param a !0, activate the button; 0, deactivate the button;
*/
virtual void setActivatedNoCallback(int a);
/**
Get the active state of the button.
@see setActivatedButton()
@ret activated !0, active; 0, inactive;
*/
virtual int getActivatedButton();
/**
Render borders around the button?
@param b !0, borders; 0, no borders;
*/
void setBorders(int b);
/**
Sets the border style for the button. This
has no effect if no borders are being drawn.
"button_normal" A normal button.
"osbutton_normal" A normal OS button (if in Windows, will show a std win32 button).
"osbutton_close" An OS close button.
"osbutton_minimize" An OS minimize button.
"osbutton_maximize" An OS maximize button.
@see getBorderStyle()
@param style The style of button you want.
*/
void setBorderStyle(const wchar_t *style);
/**
Get the border style of the button (if there is one).
If no border is drawn, this method always returns NULL.
@see setBorderStyle()
@ret The border style.
*/
const wchar_t *getBorderStyle();
/**
Set the inactive alpha blending value. This is the alpha blending
value that will be used for blending when the button does NOT have focus.
@param a The alpha value, range is from 0 (fully transparent) to 255 (fully opaque).
*/
void setInactiveAlpha(int a);
/**
Set the active alpha blending value. This is the alpha blending value
that will be used for blending when the button HAS focus.
@param a The alpha value, range is from 0 (fully transparent) to 255 (fully opaque).
*/
void setActiveAlpha(int a);
/**
Sets the colors for various states of our button. This is
done via element id's which are in the skin xml or registered
as seperate xml.
@param text Normal text color (window has focus but button is not active).
@param hilite Hilited text color (button has focus).
@param dimmed Dimmed text color (parent window doesn't even have focus).
*/
void setColors(const wchar_t *text=L"studio.button.text", const wchar_t *hilite=L"studio.button.hiliteText", const wchar_t *dimmed=L"studio.button.dimmedText");
/**
Deletes the regions and resets them to NULL.
@see reloadResources()
*/
virtual void freeResources();
/**
Reinitializes regions for which there are bitmaps available.
@see freeResources()
*/
virtual void reloadResources();
/**
Event is triggered when the is being activated.
Override this event to implement your own behavior.
@see setActivatedButton()
@ret 1
@param active The button's state (nonzero is active).
*/
virtual int onActivateButton(int active);
/**
Returns the current region of the button.
@see api_region
@ret The region of the button.
*/
virtual api_region *getRegion();
/**
Set the modal return. This is what will be returned
when the window is closed and the window is set to modal.
@param r The return code you wish to set.
*/
virtual void setModalRetCode(int r);
/**
Get the modal return code for the window.
@ret The modal return code.
*/
virtual int getModalRetCode() const;
/**
Event is triggered when the button is about to be initialized.
Override this event to implement your own behavior.
@ret 1
*/
virtual int onInit();
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
virtual void setTextColor(const wchar_t *text);
virtual void setTextHoverColor(const wchar_t *text);
virtual void setTextDimmedColor(const wchar_t *text);
virtual void checkState(POINT *pt=NULL);
virtual void onCancelCapture();
private:
AutoSkinBitmap normalbmp, pushedbmp, hilitebmp, checkbmp, rightbmp, activatedbmp;
SkinBitmap *base_texture;
RegionI *normalrgn, *pushedrgn, *hirgn, *currgn, *activatedrgn;
int textsize;
TextAlign alignment;
SkinColor color_text, color_hilite, color_dimmed;
int retcode;
StringW normalBmpStr, pushedBmpStr, hilitedBmpStr, activatedBmpStr;
int folderstyle;
int autodim;
int userhilite;
int userdown;
int activated;
int enabled;
int borders;
const wchar_t *borderstyle;
int dsoNormal, dsoPushed, dsoDisabled;
int iwantfocus;
int center_bitmap;
int use_base_texture;
int checked;
int xShift, yShift, tile_base_texture;
int inactivealpha, activealpha;
StringW colorgroup;
int forcedown;
};
#endif
+319
View File
@@ -0,0 +1,319 @@
#include "precomp.h"
#include <api/wnd/api_wnd.h>
#include "clickwnd.h"
#include <api/wnd/notifmsg.h>
#include <api/wnd/wndclass/guiobjwnd.h>
enum
{
CLICKWND_LBUTTONDOWN = 0,
CLICKWND_LBUTTONUP,
CLICKWND_RBUTTONDOWN,
CLICKWND_RBUTTONUP,
};
ClickWnd::ClickWnd()
{
handleRight = TRUE;
button = -1;
mousedown = 0;
mcaptured = 0;
hilite = 0;
down = 0;
areacheck = 0;
}
ClickWnd::~ClickWnd()
{
BaseWnd::hintDestroying(); // so basewnd doesn't call onCancelCapture
if (getCapture()) endCapture();
}
void ClickWnd::setHandleRightClick(int tf)
{
handleRight=tf;
}
int ClickWnd::getHandleRightClick()
{
return handleRight;
}
int ClickWnd::onLeftButtonDown(int x, int y)
{
notifyParent(ChildNotify::CLICKWND_LEFTDOWN, x, y);
CLICKWND_PARENT::onLeftButtonDown(x, y);
abortTip();
#ifdef _WIN32
ifc_window *dp = getDesktopParent();
if (dp != NULL)
{
if (dp->wantActivation())
{
SetActiveWindow(getRootParent()->gethWnd());
SetFocus(getRootParent()->gethWnd());
}
else
{
HWND w = dp->gethWnd();
HWND owner = GetWindow(w, GW_OWNER);
if (owner != NULL) {
SetActiveWindow(owner);
SetFocus(owner);
}
}
}
else
{
SetActiveWindow(getRootParent()->gethWnd());
}
#else
#warning port me or remove me
#endif
if (ptInRegion(x, y))
return onButtonDown(CLICKWND_LBUTTONDOWN, x, y);
else
return 1;
}
int ClickWnd::onRightButtonDown(int x, int y)
{
notifyParent(ChildNotify::CLICKWND_RIGHTDOWN, x, y);
CLICKWND_PARENT::onRightButtonDown(x, y);
abortTip();
if (!handleRight) return 1;
if (ptInRegion(x, y))
return onButtonDown(CLICKWND_RBUTTONDOWN, x, y);
else
return 1;
}
int ClickWnd::onLeftButtonUp(int x, int y)
{
notifyParent(ChildNotify::CLICKWND_LEFTUP, x, y);
CLICKWND_PARENT::onLeftButtonUp(x, y);
//jf
// if (ptInRegion())
return onButtonUp(CLICKWND_LBUTTONUP, x, y);
// else
// return 1;
}
int ClickWnd::onRightButtonUp(int x, int y)
{
notifyParent(ChildNotify::CLICKWND_RIGHTUP, x, y);
CLICKWND_PARENT::onRightButtonUp(x, y);
//jf
//if (ptInRegion())
if (!handleRight) {
onRightPush(x, y);
return 1;
}
return onButtonUp(CLICKWND_RBUTTONUP, x, y);
// else
// return 1;
}
int ClickWnd::onMouseMove(int x, int y)
{
POINT pos, rpos={x,y};
int mouseover;
CLICKWND_PARENT::onMouseMove(x, y);
pos=rpos;
clientToScreen(&pos);
int lasthilite = hilite;
mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == static_cast<ifc_window *>(this) && ptInRegion(x, y));
if (!mouseover && (!mousedown
#ifdef _WIN32
|| !Std::keyDown(button?MK_RBUTTON:MK_LBUTTON)
#else
#warning port me
#endif
)) {
if (mcaptured || getCapture()) {
endCapture();
mcaptured = 0;
}
mousedown = 0;
down = 0;
if (wantClickWndAutoInvalidate()) invalidate();
if (hilite) _onLeaveArea();
hilite = 0;
return 1;
} else if (!mouseover && hilite) {
hilite = 0;
_onLeaveArea();
} else if (mouseover && !hilite) {
hilite = 1;
_onEnterArea();
}
if (!getCapture() && mouseover) { // capture to see when leave
_enterCapture();
}
int lastdown = down;
hilite = mouseover;
#ifdef WASABI_COMPILE_WNDMGR
int m = getGuiObject() ? getGuiObject()->guiobject_getMover() : 0;
#else
int m = 0;
#endif
if (!m) {
down = userDown() || (mouseover && mousedown);
} else
down = userDown() || mousedown;
// FG> note to self now that i finally fixed this... :
// there is a potential bottleneck here, if for some reason this test is always true when moving the windows around like crazy.
if (down != lastdown || (hilite != lasthilite && !m)) {
if (wantClickWndAutoInvalidate()) invalidate();
}
//invalidate();
return 1;
}
void ClickWnd::_enterCapture()
{
//gee!! if (!hilite) _onEnterArea();
if (!getCapture()) beginCapture();
mcaptured = 1;
}
int ClickWnd::onButtonDown(int which, int x, int y)
{
if (!wantClicks()) return 1;
if (!getCapture()) {
_enterCapture();
}
mousedown = 1;
down = 1;
button = -1;
if (which == CLICKWND_LBUTTONDOWN) button = 0;
else if (which == CLICKWND_RBUTTONDOWN) button = 1;
if (wantClickWndAutoInvalidate()) invalidate();
return 1;
}
int ClickWnd::onButtonUp(int which, int x, int y)
{
// make sure same button
if (button == 0 && which == CLICKWND_RBUTTONUP) return 1;
if (button == 1 && which == CLICKWND_LBUTTONUP) return 1;
if (!down) {
if (mcaptured) {
endCapture();
mcaptured = 0;
}
if (hilite) _onLeaveArea();
hilite = 0;
mousedown = 0;
return 1;
}
POINT pos={x,y};
clientToScreen(&pos);
int mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
if (!mouseover) {
if (mcaptured) {
endCapture();
mcaptured = 0;
}
if (hilite) _onLeaveArea();
hilite = 0;
}
// it was down, process the event
int a = down;
down = 0;
mousedown = 0;
if (wantClickWndAutoInvalidate()) invalidate();
if (a) {
if (button == 0) onLeftPush(x, y);
else if (button == 1) onRightPush(x, y);
}
// we need to do this again (and get the new mouse pos) because onLeft/RightPush may have called a
// message loop and let the mouse leave without us being aware of it
Wasabi::Std::getMousePos(&x, &y);
pos.x = x;
pos.y = y;
screenToClient(&x, &y);
mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
if (!mouseover && hilite) _onLeaveArea();
else if (mouseover && !hilite) _onEnterArea();
hilite = mouseover;
return 1;
}
void ClickWnd::onSetVisible( int show )
{
CLICKWND_PARENT::onSetVisible( show );
if ( !show )
{
if ( getCapture() )
{
mcaptured = 0;
endCapture();
}
down = 0;
mousedown = 0;
if ( hilite )
_onLeaveArea();
hilite = 0;
}
}
void ClickWnd::_onEnterArea()
{
if (areacheck == 0) {
areacheck++;
onEnterArea();
} else
DebugString("onEnterArea check failed %08X \n", this);
}
void ClickWnd::_onLeaveArea()
{
if (areacheck == 1) {
areacheck--;
onLeaveArea();
} else
DebugString("onLeaveArea check failed %08X\n", this);
}
void ClickWnd::onEnterArea()
{
// DebugString("onEnterArea %08X\n", this);
}
void ClickWnd::onLeaveArea()
{
// DebugString("onLeaveArea %08X\n", this);
}
void ClickWnd::onCancelCapture()
{
CLICKWND_PARENT::onCancelCapture();
mcaptured=0;
down = 0;
mousedown = 0;
if (hilite) _onLeaveArea();
hilite = 0;
}
+74
View File
@@ -0,0 +1,74 @@
#ifndef _CLICKWND_H
#define _CLICKWND_H
// this class defines clicking behavior, i.e. detecting mouse downs and ups
// and doing captures to determine clicks
#include <bfc/common.h>
// benski> CUT: #include <api/wnd/wndclass/backbufferwnd.h>
#include <api/wnd/wndclass/abstractwndhold.h>
#ifdef WASABI_COMPILE_SKIN
#define CLICKWND_PARENT AbstractWndHolder
#else
#define CLICKWND_PARENT ServiceWndHolder
#endif
// benski> CUT: #define CLICKWND_PARENT BackBufferWnd
class NOVTABLE ClickWnd : public CLICKWND_PARENT {
public:
ClickWnd();
virtual ~ClickWnd();
void setHandleRightClick(int tf);
int getHandleRightClick();
// override these to get clicks!
virtual void onLeftPush(int x, int y) {}
virtual void onRightPush(int x, int y) {}
virtual void onLeftDoubleClick(int x, int y) {}
virtual void onRightDoubleClick(int x, int y) {}
virtual void onEnterArea();
virtual void onLeaveArea();
virtual void onSetVisible(int show);
virtual void onCancelCapture();
virtual int isInClick() { return mousedown; }
protected:
virtual int onLeftButtonDown(int x, int y);
virtual int onRightButtonDown(int x, int y);
virtual int onLeftButtonUp(int x, int y);
virtual int onRightButtonUp(int x, int y);
virtual int onMouseMove(int x, int y);
// override this and return 0 to ignore clicks
virtual int wantClicks() { return 1; }
// override this and return 1 to force down-ness
virtual int userDown() { return 0; }
virtual int getHilite() { return hilite; } // mouse is over, period
virtual int getDown() { return down; } // mouse is over and pushing down
int onButtonDown(int which, int x, int y);
int onButtonUp(int which, int x, int y);
void _enterCapture();
virtual int wantClickWndAutoInvalidate() { return 1; }
private:
void _onEnterArea();
void _onLeaveArea();
int button; // 0 == left, 1 == right, which button was pushed
int handleRight:1;
int mousedown:1;
int mcaptured:1; // we are capturing the mouse
int hilite:1; // mouse is over but not down
int down:1;
int areacheck;
};
#endif
+219
View File
@@ -0,0 +1,219 @@
#include "precomp.h"
#include <process.h>
#include "ddrawwnd.h"
#include "../bfc/canvas.h"
#include "../bfc/region.h"
DDrawWnd::DDrawWnd() {
m_lpDD = NULL;
lpClipper = NULL;
m_lpRenderSurf = NULL;
m_lpPrimSurf = NULL;
}
DDrawWnd::~DDrawWnd() {
deleteFrameBuffer(NULL);
}
void DDrawWnd::deleteFrameBuffer(Canvas *canvas) {
if (m_lpRenderSurf) m_lpRenderSurf->Release();
if (m_lpPrimSurf) m_lpPrimSurf->Release();
if (lpClipper) lpClipper->Release();
if (m_lpDD) m_lpDD->Release();
m_lpRenderSurf = NULL;
m_lpPrimSurf = NULL;
m_lpDD = NULL;
lpClipper = NULL;
ddlist.removeItem(this);
}
int DDrawWnd::onInit() {
DDRAWWND_PARENT::onInit();
if (!allow_dd) return 1;
return 1;
}
Canvas *DDrawWnd::createFrameBuffer(int _w, int _h) {
if (!allow_dd) return DDRAWWND_PARENT::createFrameBuffer(_w, _h);
if (virtualCanvas && !m_lpPrimSurf)
DDRAWWND_PARENT::deleteFrameBuffer(virtualCanvas);
deleteFrameBuffer(NULL);
int resize_h = 8;
int resize_w = 8;
w = _w;
h = _h;
if (DirectDrawCreate(NULL,&m_lpDD,NULL) != DD_OK) {
m_lpDD=NULL;
MessageBox(gethWnd(),"Error creating ddraw object","DDraw",0);
return NULL;
}
int dbl=0;
m_lpDD->SetCooperativeLevel(gethWnd(), DDSCL_NORMAL);
resize_w=(((w>>dbl)+3)&~3);
// g_noshoww=resize_w-(w>>dbl);
resize_h=h>>dbl;
DDSURFACEDESC DDsd={sizeof(DDsd),};
DDsd.dwFlags = DDSD_CAPS;
DDsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
if (m_lpDD->CreateSurface(&DDsd, &m_lpPrimSurf, NULL) != DD_OK) {
m_lpPrimSurf=0;
return NULL;
}
if (m_lpDD->CreateClipper(0, &lpClipper, NULL) != DD_OK ) {
m_lpPrimSurf->Release();
m_lpPrimSurf=0;
return NULL;
}
lpClipper->SetHWnd(0, gethWnd());
m_lpPrimSurf->SetClipper(lpClipper);
DDsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_PIXELFORMAT;
DDsd.dwWidth=resize_w;
DDsd.dwHeight=resize_h;
DDsd.lPitch=resize_w*sizeof(int);
DDsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
DDsd.ddpfPixelFormat.dwSize = sizeof(DDsd.ddpfPixelFormat);
DDsd.ddpfPixelFormat.dwFlags=DDPF_RGB;
DDsd.ddpfPixelFormat.dwRGBBitCount = 32;
DDsd.ddpfPixelFormat.dwRBitMask=0xff0000;
DDsd.ddpfPixelFormat.dwGBitMask=0x00ff00;
DDsd.ddpfPixelFormat.dwBBitMask=0x0000ff;
if (m_lpDD->CreateSurface(&DDsd, &m_lpRenderSurf, NULL) != DD_OK) {
m_lpRenderSurf->Release();
m_lpPrimSurf->Release();
lpClipper->Release();
m_lpRenderSurf=0;
m_lpPrimSurf=0;
lpClipper=0;
return NULL;
}
fb_canvas = new DDSurfaceCanvas(m_lpRenderSurf, w, h);
ddlist.addItem(this);
if (!thread)
startThread();
return fb_canvas;
}
int DDrawWnd::virtualBeforePaint(api_region *r) {
if (!allow_dd) return DDRAWWND_PARENT::virtualBeforePaint(r);
EnterCriticalSection(&DDrawWnd::cs);
fb_canvas->enter();
return 1;
}
int DDrawWnd::virtualAfterPaint(api_region *r) {
if (!allow_dd) return DDRAWWND_PARENT::virtualAfterPaint(r);
fb_canvas->exit();
LeaveCriticalSection(&DDrawWnd::cs);
return 1;
}
void DDrawWnd::virtualCanvasCommit(Canvas *canvas, RECT *internalrect, double ra) {
if (!allow_dd) { DDRAWWND_PARENT::commitFrameBuffer(canvas, internalrect, ra); return; }
internalrect->left = MAX(0, (int)internalrect->left);
internalrect->top = MAX(0, (int)internalrect->top);
internalrect->right = MAX(w, (int)internalrect->right);
internalrect->bottom = MAX(h, (int)internalrect->bottom);
RECT wr;
RECT screenrect = *internalrect;
getWindowRect(&wr);
screenrect.left += wr.left;
screenrect.top += wr.top;
screenrect.right += wr.left;
screenrect.bottom += wr.top;
if (ra == 1.0) {
if (m_lpPrimSurf->Blt(&screenrect,m_lpRenderSurf,internalrect,DDBLT_WAIT,NULL) == DDERR_SURFACELOST) {
m_lpPrimSurf->Restore();
}
} else {
RECT rcr=screenrect;
rcr.left = wr.left + (int)((double)internalrect->left*ra);
rcr.top = wr.top + (int)((double)internalrect->top*ra);
rcr.right = rcr.left + (int)((double)(internalrect->right-internalrect->left)*ra);
rcr.bottom = rcr.top + (int)((double)(internalrect->bottom-internalrect->top)*ra);
if (m_lpPrimSurf->Blt(&rcr,m_lpRenderSurf,internalrect,DDBLT_WAIT,NULL) == DDERR_SURFACELOST)
m_lpPrimSurf->Restore();
}
}
void DDrawWnd::startThread() {
DWORD id;
quitthread=0;
InitializeCriticalSection(&cs);
thread = (HANDLE)_beginthreadex(NULL,0,renderThread,0,0,(unsigned int *)&id);
}
void DDrawWnd::stopThread() {
quitthread = 1;
}
unsigned int WINAPI DDrawWnd::renderThread(void *) {
while (!quitthread) {
for (int i=0;i<ddlist.getNumItems();i++)
ddlist.enumItem(i)->flushPaint();
Sleep(MIN(MAX(sleep_val,1),100));
}
_endthreadex(0);
return 1;
}
void DDrawWnd::invalidate() {
if (!allow_dd) { DDRAWWND_PARENT::invalidate(); return; }
DDRAWWND_PARENT::deferedInvalidate();
}
void DDrawWnd::invalidateRect(RECT *r) {
if (!allow_dd) { DDRAWWND_PARENT::invalidateRect(r); return; }
DDRAWWND_PARENT::deferedInvalidateRect(r);
}
void DDrawWnd::invalidateRgn(api_region *rgn) {
if (!allow_dd) { DDRAWWND_PARENT::invalidateRgn(rgn); return; }
DDRAWWND_PARENT::deferedInvalidateRgn(rgn);
}
void DDrawWnd::validate() {
if (!allow_dd) { DDRAWWND_PARENT::validate(); return; }
DDRAWWND_PARENT::deferedValidate();
}
void DDrawWnd::validateRect(RECT *r) {
if (!allow_dd) { DDRAWWND_PARENT::validateRect(r); return; }
DDRAWWND_PARENT::deferedValidateRect(r);
}
void DDrawWnd::validateRgn(api_region *rgn) {
if (!allow_dd) { DDRAWWND_PARENT::validateRgn(rgn); return; }
DDRAWWND_PARENT::deferedValidateRgn(rgn);
}
CRITICAL_SECTION DDrawWnd::cs;
HANDLE DDrawWnd::thread=NULL;
int DDrawWnd::quitthread=0;
PtrList<DDrawWnd> DDrawWnd::ddlist;
int DDrawWnd::allow_dd = 1;
int DDrawWnd::sleep_val = 10;
+60
View File
@@ -0,0 +1,60 @@
#ifndef __DDRAWWND_H
#define __DDRAWWND_H
#include <ddraw.h>
#include "../bfc/basewnd.h"
class DDSurfaceCanvas;
class DDrawWnd;
class api_region;
#define DDRAWWND_PARENT BaseWnd
class NOVTABLE DDrawWnd : public DDRAWWND_PARENT {
public:
DDrawWnd();
virtual ~DDrawWnd();
virtual int virtualBeforePaint(api_region *r);
virtual int virtualAfterPaint(api_region *r);
virtual void virtualCanvasCommit(Canvas *canvas, RECT *r, double ratio);
virtual Canvas *createFrameBuffer(int w, int h);
virtual void deleteFrameBuffer(Canvas *canvas);
virtual int onInit();
virtual void invalidate();
virtual void invalidateRect(RECT *r);
virtual void invalidateRgn(api_region *rgn);
virtual void validate();
virtual void validateRect(RECT *r);
virtual void validateRgn(api_region *rgn);
private:
void initDDraw();
void startThread();
void stopThread();
LPDIRECTDRAW m_lpDD;
LPDIRECTDRAWSURFACE m_lpRenderSurf, m_lpPrimSurf;
DDSurfaceCanvas *fb_canvas;
int w, h;
LPDIRECTDRAWCLIPPER lpClipper;
static int allow_dd;
static int sleep_val;
static CRITICAL_SECTION cs;
static HANDLE thread;
static int quitthread;
static PtrList<DDrawWnd> ddlist;
static unsigned int WINAPI renderThread(void *);
};
#endif
File diff suppressed because it is too large Load Diff
+134
View File
@@ -0,0 +1,134 @@
//NONPORTABLE
#ifndef _EDITWND_H
#define _EDITWND_H
#include <api/wnd/wndclass/guiobjwnd.h>
#include <tataki/color/skinclr.h>
#include <api/wnd/usermsg.h>
#include <bfc/common.h>
#define EDITWND_PARENT GuiObjectWnd
class EditWnd : public EDITWND_PARENT {
public:
EditWnd(wchar_t *buffer=NULL, int buflen=0);
virtual ~EditWnd();
virtual int onInit();
virtual int onPaint(Canvas *canvas);
virtual int onResize();
#ifdef WIN32
virtual LRESULT wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
// mig: Made these virtual to allow to be accessed by
// EditWndString object in editwndstring.h
virtual void setBuffer(wchar_t *buffer, int len);
virtual void getBuffer(wchar_t *outbuf, int len);
virtual const wchar_t *getBufferPtr() { return outbuf; }
virtual int getBufferLength() { return maxlen; }
virtual void setBackgroundColor(ARGB32 c);
virtual void setTextColor(ARGB32 c);
void setModal(int modal); //if modal, deletes self on enter
void setAutoEnter(int a); //fake an onEnter event when lose focus
int getAutoEnter() { return autoenter; }
void setAutoSelect(int a); //true==grab the focus on init
void setIdleTimerLen(int ms); // how many ms keys are idle before send msg
virtual void onSetVisible(int show);
virtual int onGetFocus();
virtual int wantFocus();
virtual void setWantFocus(int w) { wantfocus = w; }
virtual void selectAll();
virtual void enter();
virtual void setIdleEnabled(int i) { idleenabled = i; }
virtual int getIdleEnabled() { return idleenabled; }
void setBorder(int border);
int getTextLength();
HWND getEditWnd();
virtual int handleRatio() { return 0; }
virtual int getAutoSelect() { return autoselect; }
void setMultiline(int ml);
void setReadOnly(int ro);
void setPassword(int pw);
void setAutoHScroll(int hs);
void setAutoVScroll(int vs);
void setVScroll(int vs);
int isEditorKey(int vk);
virtual void invalidate();
virtual int gotFocus();
// the wndproc for the edit box
virtual LRESULT editWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:
virtual void timerCallback(int id);
// call down on these if you override them
virtual void onEditUpdate();
virtual void onIdleEditUpdate();
virtual int onEnter(); // user hit enter.. return 1 to close window
virtual int onAbort(); // user hit escape.. return 1 to close window
virtual int onLoseFocus(); // different from onKillFocus() from BaseWnd!
void setStyle(LONG style, int set);
#ifdef LINUX
virtual int onLeftButtonDown( int x, int y );
virtual int onLeftButtonUp( int x, int y );
virtual int onMouseMove( int x, int y );
virtual int onKeyDown(int key);
#endif
private:
#ifdef LINUX
int textposFromCoord( int x, int y );
#endif
HWND editWnd;
WNDPROC prevWndProc;
int maxlen;
int retcode;
int idletimelen;
int modal;
int bordered;
int autoenter;
int beforefirstresize;
int autoselect;
int multiline;
int readonly;
int password;
int idleenabled;
int autohscroll,autovscroll,vscroll;
int nextenterfaked;
SkinColor backgroundcolor, textcolor, selectioncolor;
#ifdef LINUX
int selstart, selend;
int cursorpos;
int selectmode;
int viewstart;
#endif
#ifdef WIN32
HBRUSH oldbrush;
#endif
// Basically, we're redoing the functionality of EditWndString
// (the bigger version), so we'll probably erase EditWndString
// completely as an object.
MemBlock<wchar_t> buffer8;
wchar_t *outbuf;
int wantfocus;
#ifdef LINUX
StringW inbuf;
#endif
};
#define EDITWND_RETURN_NOTHING 0 // user didn't do nothing
#define EDITWND_RETURN_OK 1 // user hit return
#define EDITWND_RETURN_CANCEL 2 // user hit escape or something
#endif
@@ -0,0 +1,17 @@
#include <precomp.h>
#include "editwndstring.h"
// ===========================================================================
//
// NULLSOFT WASABI SDK MODULE & EXAMPLE CODE
//
// File: editwndstring.cpp
//
//!## Purpose: The EditWndString object both extends the EditWnd object to
//!## simplify and streamline the use of an EditWnd in your wasabi
//!## components. In addition, this module serves as a tutorial
//!## to instruct wasabi developers on how to properly extend our
//!## current objects to provide new functionality.
//
//
@@ -0,0 +1,24 @@
#ifndef _EDITWNDSTRING_H
#define _EDITWNDSTRING_H
#include <api/wnd/wndclass/editwnd.h>
#include <bfc/memblock.h>
class EditWndString : public EditWnd
{
public:
void setBuffer(wchar_t *buffer, int len=0)
{
b.setSize(len+1);
wchar_t *bufmem=b.getMemory();
if(len)
wcsncpy(bufmem,buffer,len);
bufmem[len]=0;
EditWnd::setBuffer(bufmem,len);
}
const wchar_t *getBuffer() { return b.getMemory(); }
private:
MemBlock<wchar_t> b;
};
#endif//_EDITWNDSTRING_H
+143
View File
@@ -0,0 +1,143 @@
#include "precomp.h"
#include "embeddedxui.h"
EmbeddedXuiObject::EmbeddedXuiObject() {
embedded = NULL;
myxuihandle = newXuiHandle();
getScriptObject()->vcpu_setInterface(embeddedXuiGuid, (void *)static_cast<EmbeddedXuiObject *>(this));
getScriptObject()->vcpu_setClassName(L"ObjectEmbedded"); // this is the script class name
getScriptObject()->vcpu_setController(embeddedXuiController);
}
EmbeddedXuiObject::~EmbeddedXuiObject() {
paramlist.deleteAll();
}
void EmbeddedXuiObject::onNewContent() {
embeddedxui_onNewEmbeddedContent();
}
void EmbeddedXuiObject::embeddedxui_onNewEmbeddedContent() {
embedded = NULL;
const wchar_t *id = embeddedxui_getEmbeddedObjectId();
if (id != NULL && *id) {
GuiObject *myself = getGuiObject();
embedded = myself->guiobject_findObject(id);
if (embedded != NULL && embedded != myself) {
foreach(paramlist)
EmbeddedXuiObjectParam *p = paramlist.getfor();
embedded->guiobject_setXmlParam(p->param, p->value);
endfor;
#ifdef WASABI_COMPILE_CONFIG
syncCfgAttrib();
#endif
}
}
}
int EmbeddedXuiObject::onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value) {
int r = EMBEDDEDXUIOBJECT_PARENT::onUnknownXuiParam(xmlattributename, value);
paramlist.addItem(new EmbeddedXuiObjectParam(xmlattributename, value));
if (embedded)
r = embedded->guiobject_setXmlParam(xmlattributename, value);
return r;
}
int EmbeddedXuiObject::onInit()
{
int r = EMBEDDEDXUIOBJECT_PARENT::onInit();
const wchar_t *id = embeddedxui_getContentId();
if (id != NULL && *id)
setContent(id);
return r;
}
#ifdef WASABI_COMPILE_CONFIG
int EmbeddedXuiObject::onReloadConfig() {
int r = EMBEDDEDXUIOBJECT_PARENT::onReloadConfig();
syncCfgAttrib();
return r;
}
#endif
#ifdef WASABI_COMPILE_CONFIG
void EmbeddedXuiObject::syncCfgAttrib()
{
if (embedded == NULL) return;
CfgItem *item = getGuiObject()->guiobject_getCfgItem();
const wchar_t *attrib = getGuiObject()->guiobject_getCfgAttrib();
if (item != embedded->guiobject_getCfgItem() ||
attrib != embedded->guiobject_getCfgAttrib()) {
embedded->guiobject_setCfgAttrib(item, attrib);
}
}
#endif
// -----------------------------------------------------------------------
// Script Object
EmbeddedXuiScriptController _embeddedXuiController;
EmbeddedXuiScriptController *embeddedXuiController = &_embeddedXuiController;
// -- Functions table -------------------------------------
function_descriptor_struct EmbeddedXuiScriptController::exportedFunction[] = {
{L"getEmbeddedObject", 0, (void*)EmbeddedXuiScriptController::EmbeddedXui_getEmbeddedObject},
};
ScriptObject *EmbeddedXuiScriptController::instantiate() {
EmbeddedXuiObject *ex = new EmbeddedXuiObject;
ASSERT(ex != NULL);
return ex->getScriptObject();
}
void EmbeddedXuiScriptController::destroy(ScriptObject *o) {
EmbeddedXuiObject *ex= static_cast<EmbeddedXuiObject *>(o->vcpu_getInterface(embeddedXuiGuid));
ASSERT(ex != NULL);
delete ex;
}
void *EmbeddedXuiScriptController::encapsulate(ScriptObject *o) {
return NULL; // no encapsulation for DropDownlist yet
}
void EmbeddedXuiScriptController::deencapsulate(void *o) {
}
int EmbeddedXuiScriptController::getNumFunctions() {
return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
}
const function_descriptor_struct *EmbeddedXuiScriptController::getExportedFunctions() {
return exportedFunction;
}
scriptVar EmbeddedXuiScriptController::EmbeddedXui_getEmbeddedObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
SCRIPT_FUNCTION_INIT
EmbeddedXuiObject *ex = static_cast<EmbeddedXuiObject*>(o->vcpu_getInterface(embeddedXuiGuid));
ScriptObject *_o = NULL;
if (ex) {
GuiObject *go = ex->embeddedxui_getEmbeddedObject();
if (go != NULL)
_o = go->guiobject_getScriptObject();
}
return MAKE_SCRIPT_OBJECT(_o);
}
ScriptObject *EmbeddedXuiScriptController::cast(ScriptObject *o, GUID g) {
EmbeddedXuiObject *exo = static_cast<EmbeddedXuiObject *>(o->vcpu_getInterface(embeddedXuiGuid));
if (!exo) return NULL;
GuiObject *go = exo->embeddedxui_getEmbeddedObject();
if (go != NULL) {
ScriptObject *eo = go->guiobject_getScriptObject();
if (eo != NULL) {
void *i = eo->vcpu_getInterface(g);
if (i != NULL)
return eo;
}
}
return NULL;
}
ScriptObjectController *EmbeddedXuiScriptController::getAncestorController() { return WASABI_API_MAKI->maki_getController(guiObjectGuid); }
+88
View File
@@ -0,0 +1,88 @@
#ifndef __EMBEDDEDXUIOBJECT_H
#define __EMBEDDEDXUIOBJECT_H
#include <wasabicfg.h>
#include <api/script/api_maki.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <api/script/scriptguid.h>
#include <api/script/scriptobj.h>
#include <api/script/objcontroller.h>
#define EMBEDDEDXUIOBJECT_PARENT GuiObjectWnd
class EmbeddedXuiObjectParam {
public:
EmbeddedXuiObjectParam(const wchar_t *p, const wchar_t *v) : param(p), value(v) {}
virtual ~EmbeddedXuiObjectParam() {}
StringW param;
StringW value;
};
class EmbeddedXuiObject : public EMBEDDEDXUIOBJECT_PARENT {
public:
EmbeddedXuiObject();
virtual ~EmbeddedXuiObject();
virtual void onNewContent();
virtual int onInit();
virtual void embeddedxui_onNewEmbeddedContent();
virtual const wchar_t *embeddedxui_getContentId() { return NULL; }
virtual const wchar_t *embeddedxui_getEmbeddedObjectId() { return NULL; }
virtual int onUnknownXuiParam(const wchar_t *xmlattributename, const wchar_t *value);
#ifdef WASABI_COMPILE_CONFIG
virtual int onReloadConfig();
#endif
virtual GuiObject *embeddedxui_getEmbeddedObject() { return embedded; }
private:
#ifdef WASABI_COMPILE_CONFIG
void syncCfgAttrib();
#endif
int myxuihandle;
PtrList<EmbeddedXuiObjectParam> paramlist;
GuiObject *embedded;
};
// -----------------------------------------------------------------------
class EmbeddedXuiScriptController: public ScriptObjectControllerI
{
public:
virtual const wchar_t *getClassName() { return L"ObjectEmbedder"; }
virtual const wchar_t *getAncestorClassName() { return L"GuiObject"; }
virtual ScriptObjectController *getAncestorController();
virtual int getNumFunctions();
virtual const function_descriptor_struct *getExportedFunctions();
virtual GUID getClassGuid() { return embeddedXuiGuid; }
virtual ScriptObject *instantiate();
virtual void destroy(ScriptObject *o);
virtual void *encapsulate(ScriptObject *o);
virtual void deencapsulate(void *o);
virtual ScriptObject *cast(ScriptObject *o, GUID g);
private:
static function_descriptor_struct exportedFunction[];
static scriptVar EmbeddedXui_getEmbeddedObject(SCRIPT_FUNCTION_PARAMS, ScriptObject *o);
};
extern COMEXP EmbeddedXuiScriptController *embeddedXuiController;
#endif
@@ -0,0 +1,60 @@
#include "precomp.h"
#include "foreignwnd.h"
PtrListQuickSorted<ForeignWndProc, ForeignWndProcComparator> ForeignWnd::foreignwndprocs;
LRESULT CALLBACK foreignWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ForeignWndProc *wp = ForeignWnd::foreignwndprocs.findItem((const wchar_t *)hwnd);
if (wp)
{
if (uMsg == WM_SHOWWINDOW) // more ?
wp->wnd->wndProc(hwnd, uMsg, wParam, lParam);
return CallWindowProc(wp->oldWindowProc, hwnd, uMsg, wParam, lParam);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
ForeignWnd::ForeignWnd(OSWINDOWHANDLE wndhandle, OSMODULEHANDLE module, int subclass)
{
thishwnd = wndhandle;
setOSModuleHandle(module);
#ifdef EXPERIMENTAL_INDEPENDENT_AOT
DebugString("ForeignWnd::ForeignWnd(OSWINDOWHANDLE wndhandle): There might be problems with GWL_USERDATA assumptions when EXPERIMENTAL_INDEPENDENT_AOT is on, lone should audit\n");
#endif
// access protected basewnd member
hwnd = wndhandle;
setForeignWnd(1);
if (subclass)
{
oldWindowProc = (WNDPROC) GetWindowLongPtrW(wndhandle, GWLP_WNDPROC);
wndprocentry = new ForeignWndProc;
wndprocentry->wnd = this;
wndprocentry->hwnd = thishwnd;
wndprocentry->oldWindowProc = oldWindowProc;
foreignwndprocs.addItem(wndprocentry);
SetWindowLongPtrW(thishwnd, GWLP_WNDPROC, (LONG_PTR)foreignWindowProc);
}
else
{
oldWindowProc = NULL;
wndprocentry = NULL;
}
}
ForeignWnd::~ForeignWnd()
{
if (wndprocentry && oldWindowProc)
{
foreignwndprocs.removeItem(wndprocentry);
delete wndprocentry;
wndprocentry = NULL;
SetWindowLongPtrW(thishwnd, GWLP_WNDPROC, (LONG_PTR)oldWindowProc);
oldWindowProc = NULL;
}
}
+56
View File
@@ -0,0 +1,56 @@
#ifndef __FOREIGNWND_H
#define __FOREIGNWND_H
#ifdef _WIN32
#include <api/wnd/basewnd.h>
class ForeignWnd;
class ForeignWndProc
{
public:
ForeignWnd *wnd;
HWND hwnd;
WNDPROC oldWindowProc;
};
class ForeignWndProcComparator
{
public:
// comparator for sorting
static int compareItem(ForeignWndProc *p1, ForeignWndProc* p2)
{
return CMP3(p1->hwnd, p2->hwnd);
}
// comparator for searching
static int compareAttrib(const wchar_t *attrib, ForeignWndProc *item)
{
return CMP3((HWND)attrib, item->hwnd);
}
};
class ForeignWnd : public BaseWnd
{
public:
// takes over an existing OSWINDOWHANDLE and wraps a BaseWnd around it
// but does not changes the windowproc, nor does it inserts the wnd
// into the system list. It does not either (under windows anyway)
// sets the userdata windowlong to the object pointer.
// if subclass is true, we subclas the windowproc and process events
// as if the window was a real rootwnd
ForeignWnd(OSWINDOWHANDLE w, OSMODULEHANDLE m, int subclass = 0);
virtual ~ForeignWnd();
static PtrListQuickSorted<ForeignWndProc, ForeignWndProcComparator> foreignwndprocs;
private:
WNDPROC oldWindowProc;
HWND thishwnd;
ForeignWndProc *wndprocentry;
};
#else
#warning port me
#endif
#endif
+777
View File
@@ -0,0 +1,777 @@
#include <precomp.h>
#include "framewnd.h"
#include <api/wnd/notifmsg.h>
#include <bfc/bfc_assert.h>
#include <tataki/canvas/canvas.h>
#include <api/wnd/PaintCanvas.h>
#include <bfc/wasabi_std_wnd.h>
#define DC_FWFOCUS 0x5122
FrameWnd::FrameWnd()
{
// sizer = NULL;
SNAP=1;
snapoffsety=0;
snapoffsetx=0;
nchild = 0;
for (int i = 0; i < MAXCHILD; i++) {
children[i] = NULL;
rwchildren[i] = NULL;
hidey[i] = 0;
windowshaded[i] = 0;
}
vert = DIVIDER_UNDEFINED;
divideside = SDP_FROMLEFT;
pullbarpos = PULLBAR_HALF;
minwidth = PULLBAR_QUARTER-PULLBAR_EIGHTH;
maxwidth = PULLBAR_HALF;
resizeable = 0;
slidemode = FRAMEWND_SQUISH;
prevpullbarpos = -1;
maxpixels=0;
minpixels=0;
noMaxRestriction = false;
ZERO(sizerRect);
h_bitmap = L"wasabi.framewnd.horizontaldivider";
v_bitmap = L"wasabi.framewnd.verticaldivider";
h_grabber = L"wasabi.framewnd.horizontalgrabber";
v_grabber = L"wasabi.framewnd.verticalgrabber";
ws_bitmap = L"wasabi.framewnd.windowshade";
resizing = 0;
}
void FrameWnd::Set_v_bitmap(const wchar_t *new_v_bitmap)
{
v_bitmap=new_v_bitmap;
if (isInited())
{
invalidate();
onResize();
}
}
void FrameWnd::Set_v_grabber(const wchar_t *new_v_grabber)
{
v_grabber=new_v_grabber;
if (isInited())
{
invalidate();
onResize();
}
}
FrameWnd::~FrameWnd() {
#ifdef WASABI_COMPILE_CONFIG
if (getId() != NULL) {
StringPrintfW buf(L"FrameWnd/ws,%s", getId());
WASABI_API_CONFIG->setIntPrivate(buf, windowshaded[0]);
}
#endif
if (children[0]) // do we have any basewnd ?
for (int i = 0; i < nchild; i++) delete children[i];
}
int FrameWnd::onInit() {
int i;
FRAMEWND_PARENT::onInit();
ASSERT(vert != DIVIDER_UNDEFINED || nchild == 0);
// have to set children for frame windows
// fill in members
nchild = 0;
// make children create their windows
for (i = 0; i < MAXCHILD; i++) {
if (rwchildren[i] != NULL) {
if (rwchildren[i]->init(this) != 0) {
rwchildren[i]->setParent(this);
nchild++;
}
}
}
prevpullbarpos = pullbarpos;
if (nchild >= MAXCHILD) {
int which = (divideside == SDP_FROMLEFT) ? 0 : 1;
rwchildren[which]->bringToFront();
}
#ifdef WASABI_COMPILE_CONFIG
if (getId() != NULL) {
StringPrintfW buf(L"FrameWnd/ws,%s", getId());
int ws = WASABI_API_CONFIG->getIntPrivate(buf, /*rwchildren[0] && rwchildren[0]->childNotify(NULL, CHILD_WINDOWSHADE_CAPABLE)*/ 0);
if (ws) {
windowshade(0, !ws);
windowshade(0, ws);
pullbarpos = 0;
}
}
#endif
return 1;
}
int FrameWnd::getCursorType(int x, int y) {
RECT r;
getClientRect(&r);
POINT pt={x,y};
if (y > r.top + getLabelHeight() && Wasabi::Std::pointInRect(sizerRect, pt)) {
if (vert == DIVIDER_HORIZONTAL) return BASEWND_CURSOR_NORTHSOUTH;
else return BASEWND_CURSOR_EASTWEST;
}
return BASEWND_CURSOR_POINTER;
}
int FrameWnd::setChildren(BaseWnd *newchild1, BaseWnd *newchild2) {
return _setChildren(newchild1, newchild2, newchild1, newchild2);
}
int FrameWnd::setChildrenRootWnd(ifc_window *child1, ifc_window *child2/* =NULL */) {
return _setChildren(child1, child2, NULL, NULL);
}
int FrameWnd::_setChildren(ifc_window *child1, ifc_window *child2, BaseWnd *child1b, BaseWnd *child2b) {
if (child1b) { // we can delete them later
children[0] = child1b;
children[1] = child2b;
}
rwchildren[0] = child1;
rwchildren[1] = child2;
nchild = 0;
if (rwchildren[0] != NULL) nchild++;
if (rwchildren[1] != NULL) nchild++;
ASSERTPR(nchild >= 1, "framewnd must have one or more children");
if (isInited()) {
invalidate();
onResize();
}
return nchild;
}
ifc_window *FrameWnd::enumChild(int which) {
if (which < 0 || which >= MAXCHILD) return NULL;
return rwchildren[which];
}
int FrameWnd::childNotify(ifc_window *which, int msg, intptr_t param1, intptr_t param2) {
// ASSERT(which == rwchildren[0] || which == rwchildren[1] || which == NULL);
switch (msg) {
case ChildNotify::FRAMEWND_SETTITLEWIDTH:
if (pullbarpos == param1) return 0;
ASSERT(param1 >= 0);
if (which == rwchildren[0]) {
// rwchildren[1]->invalidate(); //FG> removed due to change in redraw layout
// rwchildren[1]->repaint();
ASSERT(divideside == SDP_FROMLEFT);
} else {
// rwchildren[0]->invalidate();
// rwchildren[0]->repaint();
ASSERT(divideside == SDP_FROMRIGHT);
}
pullbarpos = param1;
// do it
onResize();
return 1;
case ChildNotify::HIDEYHIDEY:
if (which == rwchildren[0]) hidey[0] = 1;
else if (which == rwchildren[1]) hidey[1] = 1;
which->setVisible(FALSE);
onResize();
return 1;
case ChildNotify::UNHIDEYHIDEY:
if (which == rwchildren[0]) hidey[0] = 0;
else if (which == rwchildren[1]) hidey[1] = 0;
which->setVisible(TRUE);
onResize();
return 1;
case ChildNotify::FRAMEWND_QUERY_SLIDE_MODE:
return getSlideMode();
case ChildNotify::FRAMEWND_SET_SLIDE_MODE:
setSlideMode((FrameWndSlideMode)param1);
break;
case ChildNotify::GOTFOCUS:
case ChildNotify::KILLFOCUS:
invalidateLabel();
break;
}
return FRAMEWND_PARENT::childNotify(which, msg, param1, param2);
}
/*int FrameWnd::forceFocus() {
if (!canShowFocus()) return 0; // we aren't showing a label
int v = 0;
if (nchild > 0 && rwchildren[0] != NULL) {
if (!rwchildren[0]->canShowFocus()) v |= rwchildren[0]->gotFocus();
}
if (nchild > 1 && rwchildren[1] != NULL) {
if (!rwchildren[1]->canShowFocus()) v |= rwchildren[1]->gotFocus();
}
return v;
}*/
void FrameWnd::setDividerType(FrameWndDividerType type) {
vert = type;
ASSERT(vert == DIVIDER_VERTICAL || vert == DIVIDER_HORIZONTAL);
if (isInited())
onResize();
}
FrameWndDividerType FrameWnd::getDividerType() {
return vert;
}
int FrameWnd::ConvertPixToProp() {
RECT r;
int w;
getClientRect(&r);
if(vert == DIVIDER_VERTICAL) {
w = r.right-r.left;
} else {
w = r.bottom-r.top;
}
w = (pullbarpos * PULLBAR_FULL) / w;
return w;
}
int FrameWnd::convertPropToPix(int prop) {
RECT r;
int w;
getClientRect(&r);
if(vert == DIVIDER_VERTICAL) {
w = r.right-r.left;
} else {
w = r.bottom-r.top;
}
return (w * prop) / PULLBAR_FULL;
}
int FrameWnd::setDividerPosNoCfg(int from, int pos) {
divideside = from;
ASSERT(pos >= 0);
pullbarpos = pos;
if (isInited())
onResize();
StringPrintfW buf(L"FrameWnd/%s,p", getId());
WASABI_API_CONFIG->setIntPrivate(buf, pullbarpos);
return 1;
}
int FrameWnd::setDividerPos(int from, int pos) {
#ifdef WASABI_COMPILE_CONFIG
if (getId() != NULL) {
StringPrintfW buf(L"FrameWnd/%s,p", getId());
pos = WASABI_API_CONFIG->getIntPrivate(buf, pos);
if (pos <= 0) pos = 0;
else if (pos >= PULLBAR_FULL) pos = PULLBAR_FULL;
}
#endif
return setDividerPosNoCfg(from, pos);
}
void FrameWnd::getDividerPos(int *from, int *pos) {
if (from != NULL) *from = divideside;
if (pos != NULL) *pos = pullbarpos;
}
int FrameWnd::setResizeable(int is) {
int prev = resizeable;
resizeable = is;
return prev;
}
void FrameWnd::setMinWidth(int min) {
//ASSERT(min >= 0);
minpixels = min;
}
void FrameWnd::setMaxWidth(int max)
{
//ASSERT(max >= 0);
maxpixels=max;
noMaxRestriction = (max == 0);
//maxwidth = max;
}
void FrameWnd::setSlideMode(FrameWndSlideMode mode) {
slidemode = mode;
if (isInited())
onResize();
}
FrameWndSlideMode FrameWnd::getSlideMode() {
return slidemode;
}
int FrameWnd::dragEnter(ifc_window *sourceWnd) {
ifc_window *ch = getWindowShadedChild();
if (ch == NULL) return FRAMEWND_PARENT::dragEnter(sourceWnd);
return ch->getDragInterface()->dragEnter(sourceWnd);
}
int FrameWnd::dragOver(int x, int y, ifc_window *sourceWnd) {
ifc_window *ch = getWindowShadedChild();
if (ch == NULL) return FRAMEWND_PARENT::dragOver(x, y, sourceWnd);
return ch->getDragInterface()->dragOver(-1, -1, sourceWnd);
}
int FrameWnd::dragLeave(ifc_window *sourceWnd) {
ifc_window *ch = getWindowShadedChild();
if (ch == NULL) return FRAMEWND_PARENT::dragLeave(sourceWnd);
return ch->getDragInterface()->dragLeave(sourceWnd);
}
int FrameWnd::dragDrop(ifc_window *sourceWnd, int x, int y) {
ifc_window *ch = getWindowShadedChild();
if (ch == NULL) return FRAMEWND_PARENT::dragDrop(sourceWnd, x, y);
return ch->getDragInterface()->dragDrop(sourceWnd, x, y);
}
int FrameWnd::onResize()
{
int rt = FRAMEWND_PARENT::onResize();
if (!isInited()) return rt;
RECT r;
int sizerwidth = SIZERWIDTH;
if (!isInited()) {
prevpullbarpos = pullbarpos;
return 1; // no window to resize
}
getClientRect(&r);
ASSERT(nchild >= 0);
if (nchild == 0) {
prevpullbarpos = pullbarpos;
return 1;
}
if (hidey[0] && hidey[1]) return 0; // both windows are hiding
// if we have only one child, it takes up all the room
if (hidey[0]) {
rwchildren[1]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
return 1;
} else if (hidey[1]) {
rwchildren[0]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
return 1;
}
if (nchild == 1) {
if (rwchildren[0] != NULL) rwchildren[0]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
else if (rwchildren[1] != NULL) rwchildren[1]->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
return 1;
}
#ifdef ASSERTS_ENABLED
for (int i = 0; i < nchild; i++) {
ASSERT(rwchildren[i] != NULL);
}
#endif
if (!resizeable) sizerwidth = 0;
// resize the subwindows
int w;
if (vert == DIVIDER_VERTICAL) {
w = r.right-r.left;
} else {
w = r.bottom-r.top;
}
int clientwidth = w; // the logical width
switch (pullbarpos) {
case PULLBAR_FULL: /*w = w;*/ break;
case PULLBAR_HALF: w = w/2; break;
case PULLBAR_QUARTER: w = w/4; break;
case PULLBAR_THREEQUARTER: w = w - w/4; break;
case PULLBAR_EIGHTH: w = w/8; break;
default: w = pullbarpos; break;
}
// maxpixels holds normally a negative or zero value!
if (divideside == SDP_FROMRIGHT)
{
w = (clientwidth - w);
if (maxpixels < 1 && w < -maxpixels) w = -maxpixels; // Martin> This fixes an ugly drawing overlap
// TODO: check non-relative width as well, imoh we should rewrite this function from scrap.
}
else // FROMLEFT
{
if (maxpixels < 1 && w > clientwidth + maxpixels)
w = clientwidth + maxpixels;
if (w < minpixels)
w = minpixels;
}
RECT r1, r2;
if (slidemode == FRAMEWND_COVER) { // cover mode
ASSERTPR(vert == DIVIDER_VERTICAL, "finish implementing");
if (divideside == SDP_FROMRIGHT) {
Wasabi::Std::setRect(&r1, r.left, r.top, r.right-r.left, r.bottom-r.top); //FG> delay resize
Wasabi::Std::setRect(&r2, r.left+w, r.top, r.left+clientwidth - w, r.bottom-r.top);
} else {
Wasabi::Std::setRect(&r1, r.left, r.top, r.left+w, r.bottom-r.top); //FG> delay resize
Wasabi::Std::setRect(&r2, r.left, r.top, r.right-r.left, r.bottom-r.top);
}
sizerRect.top = r.top;
sizerRect.bottom = r.bottom;
sizerRect.left = r.left + w;
sizerRect.right = r.left + w + sizerwidth;
} else { // squish mode
// left-right
if (vert == DIVIDER_VERTICAL) {
sizerRect.top = r.top;
sizerRect.bottom = r.bottom;
if (divideside == SDP_FROMLEFT) { // from left
//FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
Wasabi::Std::setRect(&r1, r.left, r.top, w, r.bottom-r.top);
Wasabi::Std::setRect(&r2, r.left+w+sizerwidth, r.top, (r.right-r.left)-(w+sizerwidth), r.bottom-r.top);
sizerRect.left = r.left+w;
sizerRect.right = sizerRect.left + sizerwidth;
}
else { // from right
//FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
Wasabi::Std::setRect(&r1, r.left, r.top, w-sizerwidth, r.bottom-r.top);
Wasabi::Std::setRect(&r2, r.left+w, r.top, (r.right-r.left)-w, r.bottom-r.top);
sizerRect.left = r.left+w-sizerwidth;
sizerRect.right = r.left+w;
}
} else {
// top-bottom
//FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
Wasabi::Std::setRect(&r1, r.left, r.top, r.right-r.left, w);
Wasabi::Std::setRect(&r2, r.left, r.top+w+sizerwidth, r.right-r.left, (r.bottom-r.top)-(w+sizerwidth));
sizerRect.top = r.top+w;
sizerRect.bottom = r.top+w+sizerwidth;
sizerRect.left = r.left;
sizerRect.right = r.right;
}
}
//FG> Choose resizing order. optimizes redraw by avoiding temporary overlap of rwchildren
bool reverse = false;
if (vert == DIVIDER_VERTICAL) {
RECT o;
rwchildren[0]->getNonClientRect(&o);
reverse = (r1.right > o.right);
} else {
RECT o;
rwchildren[0]->getNonClientRect(&o);
reverse = (r1.bottom > o.bottom);
}
//FG> actually resize rwchildren
//FG> Warning, this is using a rect for x,y,W,H and NOT l,r,t,b
if (reverse) {
rwchildren[1]->resize(r2.left, r2.top, r2.right, r2.bottom);
rwchildren[0]->resize(r1.left, r1.top, r1.right, r1.bottom);
} else {
rwchildren[0]->resize(r1.left, r1.top, r1.right, r1.bottom);
rwchildren[1]->resize(r2.left, r2.top, r2.right, r2.bottom);
}
onResizeChildren(r1, r2);
// RECT ri = sizerRect;
#if 0
if (vert == DIVIDER_HORIZONTAL) {
ri.left -= 2;
ri.right += 2;
} else {
ri.top -= 2;
ri.bottom += 2;
}
#endif
// invalidateRect(&ri);
invalidate();
repaint();
prevpullbarpos = pullbarpos;
return 1;
}
void FrameWnd::onResizeChildren(RECT leftr, RECT rightr) {
}
int FrameWnd::onPaint(Canvas *canvas) {
RECT d;
getClientRect(&d);
if ((d.left >= d.right) || (d.top >= d.bottom)) {
return FRAMEWND_PARENT::onPaint(canvas);
}
RECT cr;
// PaintBltCanvas paintcanvas;
PaintCanvas paintcanvas;
// if only 1 child, we don't paint anything
if (nchild <= 1) return FRAMEWND_PARENT::onPaint(canvas);
if (canvas == NULL) {
if (!paintcanvas.beginPaint(this)) return 0;
canvas = &paintcanvas;
}
FRAMEWND_PARENT::onPaint(canvas);
getClientRect(&cr);
if (wantRenderBaseTexture() || !isVirtual())
renderBaseTexture(canvas, cr);
if (resizeable) {
RECT r = sizerRect;
if (vert == DIVIDER_HORIZONTAL) {
r.left -= 2;
r.right += 2;
} else {
r.top -= 2;
r.bottom += 2;
}
AutoSkinBitmap &bitmap = (vert == DIVIDER_VERTICAL) ? v_bitmap : h_bitmap;
bitmap.stretchToRectAlpha(canvas, &r);
if (vert == DIVIDER_VERTICAL) {
int h = sizerRect.bottom - sizerRect.top;
int gh = v_grabber.getHeight();
if (h > gh) {
RECT rr = sizerRect;
rr.top += (h - gh) / 2;
rr.bottom -= (h - gh) / 2;
v_grabber.stretchToRectAlpha(canvas, &rr);
}
} else {
int w = sizerRect.right - sizerRect.left;
int gw = h_grabber.getWidth();
if (w > gw) {
RECT rr = sizerRect;
rr.left += (w - gw) / 2;
rr.right -= (w - gw) / 2;
h_grabber.stretchToRectAlpha(canvas, &rr);
}
}
if (windowshaded[0]) {
RECT wr = cr;
if (vert == DIVIDER_VERTICAL) {
wr.right = r.left;
} else if (vert == DIVIDER_HORIZONTAL) {
wr.bottom = r.top;
}
ws_bitmap.stretchToRect(canvas, &wr);
}
}
return 1;
}
int FrameWnd::onLeftButtonDown(int x, int y) {
FRAMEWND_PARENT::onLeftButtonDown(x, y);
if (!resizeable) return 1;
POINT p = { x, y };
if (Wasabi::Std::pointInRect(sizerRect, p)) {
beginCapture();
RECT r;
getClientRect(&r);
x -= r.left;
y -= r.top;
snapoffsety= y - (y % SNAP);
snapoffsetx= x - (x % SNAP);
resizing = 1;
return 1;
}
return 0;
}
int FrameWnd::onMouseMove(int x, int y) {
int pos, mpos;
RECT r;
if (!resizing) return 1;
FRAMEWND_PARENT::onMouseMove(x,y);
prevpullbarpos = pullbarpos;
getClientRect(&r);
x -= r.left;
y -= r.top;
if (vert == DIVIDER_VERTICAL) {
pos = r.right - r.left;
if ((x - (x % SNAP)) == snapoffsetx)
return 1;
mpos=x;
snapoffsetx=(x - (x % SNAP));
} else {
pos = r.bottom - r.top;
if ((y - (y % SNAP)) == snapoffsety)
return 1;
mpos=y;
snapoffsety=y - (y % SNAP);
}
ASSERT(pos != 0);
if (mpos < 0) mpos = 0;
if (mpos > pos) mpos = pos;
if(divideside == SDP_FROMLEFT) {
pullbarpos = mpos;
} else {
pullbarpos = pos-mpos;
}
int realMinPixels;
if (minpixels)
{
realMinPixels=minpixels;
if (minpixels<0)
realMinPixels = (r.bottom - r.top) + minpixels;
}
else
realMinPixels = convertPropToPix(minwidth);
if (divideside == SDP_FROMLEFT)
{
if (pullbarpos < realMinPixels)
{
if (rwchildren[0] != NULL && rwchildren[0]->childNotify(NULL, ChildNotify::FRAMEWND_WINDOWSHADE_CAPABLE, 0, 0)) {
pullbarpos = 0;
windowshade(0, TRUE);
} else {
pullbarpos = realMinPixels;
}
} else {
windowshade(0, FALSE);
}
} else if (divideside == SDP_FROMRIGHT) {
if (pullbarpos < realMinPixels) {
if (rwchildren[1] != NULL /* && rwchildren[1]->childNotify(NULL, CHILD_WINDOWSHADE_CAPABLE) */) {
pullbarpos = /*convertPropToPix(PULLBAR_FULL)-*/0;
windowshade(1, TRUE);
} else {
pullbarpos = realMinPixels;
}
} else {
windowshade(1, FALSE);
}
}
if (!windowshaded[0] && !windowshaded[1]) {
// if (pullbarpos > pos-convertPropToPix(minwidth))
// pullbarpos = pos-convertPropToPix(minwidth);
int realMaxPixels;
if (maxpixels || noMaxRestriction)
{
realMaxPixels=maxpixels;
if (maxpixels<0 || noMaxRestriction)
{
if (vert == DIVIDER_VERTICAL)
realMaxPixels = (r.right - r.left) + maxpixels;
else
realMaxPixels = (r.bottom - r.top) + maxpixels;
}
}
else
realMaxPixels=convertPropToPix(maxwidth);
if (pullbarpos > realMaxPixels)
pullbarpos = realMaxPixels;
}
ASSERT(pullbarpos >= 0);
if (pullbarpos != prevpullbarpos && isInited())
onResize();
return 1;
}
int FrameWnd::onLeftButtonUp(int x, int y) {
FRAMEWND_PARENT::onLeftButtonUp(x, y);
if (resizing) {
endCapture();
resizing = 0;
#ifdef WASABI_COMPILE_CONFIG
if (getId() != NULL) {
StringPrintfW buf(L"FrameWnd/%s,p", getId());
WASABI_API_CONFIG->setIntPrivate(buf, pullbarpos);
}
#endif
return 1;
}
return 0;
}
void FrameWnd::windowshade(int which, int shaded) {
ASSERT(which == 0 || which == 1);
if (!!windowshaded[which] == !!shaded) return;
if (rwchildren[which] == NULL) return;
rwchildren[which]->childNotify(NULL, ChildNotify::FRAMEWND_WINDOWSHADE_ENABLE, shaded, 0);
windowshaded[which] = shaded;
rwchildren[which]->setVisible(!shaded);
}
ifc_window *FrameWnd::getWindowShadedChild() {
if (nchild != 2) return NULL;
if (!(windowshaded[0] | windowshaded[1])) return NULL;
return windowshaded[0] ? rwchildren[0] : rwchildren[1];
}
int FrameWnd::onGetFocus() {
postDeferredCallback(DC_FWFOCUS, 0);
return 1;
}
int FrameWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
switch (p1) {
case DC_FWFOCUS:
if (rwchildren[0]) rwchildren[0]->setFocus();
break;
default:
return FRAMEWND_PARENT::onDeferredCallback(p1, p2);
}
return 1;
}
void FrameWnd::setSnap(int snap)
{
if (snap>0)
SNAP=snap;
}
+124
View File
@@ -0,0 +1,124 @@
//NONPORTABLE
#ifndef _FRAMEWND_H
#define _FRAMEWND_H
#include <bfc/common.h>
#include <api/wnd/wndclass/labelwnd.h>
#include <tataki/bitmap/autobitmap.h>
#define MAXCHILD 2 // this had better never not be 2
typedef enum {
DIVIDER_HORIZONTAL, DIVIDER_VERTICAL, DIVIDER_UNDEFINED = -1
} FrameWndDividerType;
enum { SDP_FROMLEFT, SDP_FROMRIGHT };
#define SDP_FROMTOP SDP_FROMLEFT
#define SDP_FROMBOTTOM SDP_FROMRIGHT
typedef enum {
FRAMEWND_SQUISH,
FRAMEWND_COVER
} FrameWndSlideMode;
#define SIZERWIDTH 8
// this window holds other basewnd derived classes
#define FRAMEWND_PARENT LabelWnd
class FrameWnd : public FRAMEWND_PARENT {
public:
FrameWnd();
virtual ~FrameWnd();
virtual int onInit();
virtual int getCursorType(int x, int y);
virtual int onPaint(Canvas *canvas);
virtual int onResize();
virtual int onLeftButtonDown(int x, int y);
virtual int onMouseMove(int x, int y); // only called when mouse captured
virtual int onLeftButtonUp(int x, int y);
virtual int childNotify(ifc_window *which, int msg, intptr_t param1, intptr_t param2);
// virtual int forceFocus();
// unique to this class
int setChildren(BaseWnd *child1, BaseWnd *child2=NULL);
int setChildrenRootWnd(ifc_window *child1, ifc_window *child2=NULL);
ifc_window *enumChild(int which);
// horizontal or vertical?
void setDividerType(FrameWndDividerType type);
FrameWndDividerType getDividerType();
// where is the divider?
int setDividerPos(int from, int pos);
// this version doesn't check the cfg file for last position
int setDividerPosNoCfg(int from, int pos);
void getDividerPos(int *from, int *pos);
int setResizeable(int is);
void setMinWidth(int min);
void setMaxWidth(int max);
void setSnap(int snap);
virtual int onGetFocus();
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
// cover or squish
void setSlideMode(FrameWndSlideMode mode);
FrameWndSlideMode getSlideMode();
virtual void onResizeChildren(RECT leftr, RECT rightr);
// drag and drops are forwarded into windowshaded windows
virtual int dragEnter(ifc_window *sourceWnd);
virtual int dragOver(int x, int y, ifc_window *sourceWnd);
virtual int dragLeave(ifc_window *sourceWnd);
virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
protected:
int convertPropToPix(int prop);
int ConvertPixToProp();
void windowshade(int which, int shaded);
ifc_window *getWindowShadedChild();
void Set_v_bitmap(const wchar_t *new_v_bitmap);
void Set_v_grabber(const wchar_t *new_v_grabber);
private:
int _setChildren(ifc_window *child1, ifc_window *child2, BaseWnd *child1b, BaseWnd *child2b);
int nchild;
BaseWnd *children[MAXCHILD];
ifc_window *rwchildren[MAXCHILD];
int hidey[MAXCHILD];
int windowshaded[MAXCHILD];
FrameWndDividerType vert;
int resizeable;
FrameWndSlideMode slidemode;
int divideside;
int pullbarpos; // 0..65536
int prevpullbarpos;
int minwidth, maxwidth;
int maxpixels;
boolean noMaxRestriction;
int minpixels;
int snapoffsetx, snapoffsety;
int SNAP;
RECT sizerRect;
AutoSkinBitmap h_bitmap, v_bitmap, h_grabber, v_grabber, ws_bitmap;
int resizing;
};
#define PULLBAR_FULL 65536L
#define PULLBAR_HALF (PULLBAR_FULL/2)
#define PULLBAR_QUARTER (PULLBAR_FULL/4)
#define PULLBAR_THREEQUARTER (PULLBAR_FULL-PULLBAR_QUARTER)
#define PULLBAR_EIGHTH (PULLBAR_FULL/8)
#endif
@@ -0,0 +1,82 @@
#include <precomp.h>
#include "gradientwnd.h"
// NOTE
// works now ;)
GradientWnd::GradientWnd()
: bitmap(4,4, getOsWindowHandle())
{
cache_w = cache_h = 4;
last_w = last_h = -1;
recreate = 1;
setReverseColors(TRUE);
}
GradientWnd::~GradientWnd()
{
WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
}
int GradientWnd::onInit ()
{
int r = GRADIENTWND_PARENT::onInit();
WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
return r;
}
int GradientWnd::onPaint(Canvas *canvas)
{
ASSERT(canvas != NULL);
RECT cr = clientRect();
int w = cr.right - cr.left, h = cr.bottom - cr.top;
if (w && h)
{
if (w != last_w || h != last_h)
{
recreate=1;
}
if (w > cache_w || h > cache_h)
{
cache_w = max(w, cache_w);
cache_h = max(h, cache_h);
// round up to nearest 4
cache_w = (cache_w+3) & ~3;
cache_h = (cache_h+3) & ~3;
bitmap.DestructiveResize(cache_w,cache_h,32);
recreate = 1;
}
if (recreate)
{
ARGB32 *bits = static_cast<ARGB32*>(bitmap.getBits());
renderGradient(bits, w, h, /*pitch=*/cache_w);
last_w = w;
last_h = h;
recreate=0;
}
RECT src = {0,0,w,h};
bitmap./*getSkinBitmap()->*/blitToRect(canvas, &src, &cr, getPaintingAlpha());
//bitmap./*getSkinBitmap()->*/blitAlpha(canvas, cr.left, cr.top, getPaintingAlpha());
}
return 1;
}
void GradientWnd::onParamChange()
{
invalidate();
recreate = 1;
}
int GradientWnd::skincb_onColorThemeChanged(const wchar_t *newcolortheme)
{
// TODO: This will refresh after ca 1 sec - we need an instand redraw
invalidate();
recreate = 1;
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef _GRADIENTWND_H
#define _GRADIENTWND_H
#include <api/wnd/wndclass/guiobjwnd.h>
#include <bfc/draw/gradient.h>
#include <tataki/canvas/bltcanvas.h>
#define GRADIENTWND_PARENT GuiObjectWnd
class GradientWnd : public GRADIENTWND_PARENT, public Gradient, public SkinCallbackI {
public:
GradientWnd();
virtual ~GradientWnd();
virtual int onPaint(Canvas *canvas);
protected:
virtual void onParamChange();
private:
int recreate;
int last_w, last_h;
int cache_w, cache_h;
BltCanvas bitmap;
protected:
int onInit();
int skincb_onColorThemeChanged(const wchar_t *newcolortheme);
};
#endif
+476
View File
@@ -0,0 +1,476 @@
#include <precomp.h>
#include <api/script/api_maki.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <api/script/scriptobj.h>
#include <api/script/scriptguid.h>
#include <api/service/svcs/svc_droptarget.h>
#include <api/wnd/notifmsg.h>
#include <api/script/objects/rootobject.h>
#include <api/locales/xlatstr.h>
XMLParamPair GuiObjectWnd::params[] =
{
{GUIOBJECT_ACTIVEALPHA, L"ACTIVEALPHA"},
{GUIOBJECT_ALPHA, L"ALPHA"},
{GUIOBJECT_SETANCHOR, L"ANCHOR"},
#ifdef USEAPPBAR
{GUIOBJECT_APPBAR, L"APPBAR"},
#endif
{GUIOBJECT_CFGATTR, L"CFGATTRIB"},
{GUIOBJECT_SETCURSOR, L"CURSOR"},
{GUIOBJECT_DROPTARGET, L"DROPTARGET"},
{GUIOBJECT_ENABLED, L"ENABLED"},
{GUIOBJECT_FITTOPARENT, L"FITPARENT"},
{GUIOBJECT_FOCUSONCLICK, L"FOCUSONCLICK"},
{GUIOBJECT_GHOST, L"GHOST"},
{GUIOBJECT_H, L"H"},
{GUIOBJECT_ID, L"ID"},
{GUIOBJECT_INACTIVEALPHA, L"INACTIVEALPHA"},
{GUIOBJECT_MOVE, L"MOVE"},
{GUIOBJECT_SETNOCONTEXTMENU, L"NOCONTEXTMENU"},
{GUIOBJECT_SETNODBLCLICK, L"NODBLCLICK"},
{GUIOBJECT_SETNOLEFTCLICK, L"NOLEFTCLICK"},
{GUIOBJECT_SETNOMOUSEMOVE, L"NOMOUSEMOVE"},
{GUIOBJECT_SETNORIGHTCLICK, L"NORIGHTCLICK"},
{GUIOBJECT_NOTIFY, L"NOTIFY"},
{GUIOBJECT_NOTIFY, L"NOTIFY0"},
{GUIOBJECT_NOTIFY, L"NOTIFY1"},
{GUIOBJECT_NOTIFY, L"NOTIFY2"},
{GUIOBJECT_NOTIFY, L"NOTIFY3"},
{GUIOBJECT_NOTIFY, L"NOTIFY4"},
{GUIOBJECT_NOTIFY, L"NOTIFY5"},
{GUIOBJECT_NOTIFY, L"NOTIFY6"},
{GUIOBJECT_NOTIFY, L"NOTIFY7"},
{GUIOBJECT_NOTIFY, L"NOTIFY8"},
{GUIOBJECT_NOTIFY, L"NOTIFY9"},
{GUIOBJECT_RECTRGN, L"RECTRGN"},
{GUIOBJECT_SYSREGION, L"REGIONOP"},
{GUIOBJECT_RELATH, L"RELATH"},
{GUIOBJECT_RELATW, L"RELATW"},
{GUIOBJECT_RELATX, L"RELATX"},
{GUIOBJECT_RELATY, L"RELATY"},
{GUIOBJECT_RENDERBASETEXTURE, L"RENDERBASETEXTURE"},
{GUIOBJECT_SYSMETRICSX, L"SYSMETRICSX"},
{GUIOBJECT_SYSMETRICSY, L"SYSMETRICSY"},
{GUIOBJECT_SYSMETRICSW, L"SYSMETRICSW"},
{GUIOBJECT_SYSMETRICSH, L"SYSMETRICSH"},
{GUIOBJECT_SYSREGION, L"SYSREGION"},
{GUIOBJECT_TABORDER, L"TABORDER"},
{GUIOBJECT_TOOLTIP, L"TOOLTIP"},
{GUIOBJECT_TRANSLATE, L"TRANSLATE"},
{GUIOBJECT_USERDATA, L"USERDATA"},
{GUIOBJECT_VISIBLE, L"VISIBLE"},
{GUIOBJECT_W, L"W"},
{GUIOBJECT_WANTFOCUS, L"WANTFOCUS"},
{GUIOBJECT_X, L"X"},
{GUIOBJECT_SETX1, L"X1"},
{GUIOBJECT_SETX2, L"X2"},
{GUIOBJECT_Y, L"Y"},
{GUIOBJECT_SETY1, L"Y1"},
{GUIOBJECT_SETY2, L"Y2"},
};
GuiObjectWnd::GuiObjectWnd()
{
my_gui_object = static_cast<GuiObject *>(WASABI_API_MAKI->maki_encapsulate(guiObjectGuid, getScriptObject()));
getScriptObject()->vcpu_setInterface(xmlObjectGuid, static_cast<XmlObject *>(this));
getScriptObject()->vcpu_setInterface(guiObjectWndGuid, static_cast<GuiObjectWnd *>(this));
#ifdef USEAPPBAR
getScriptObject()->vcpu_setInterface(appBarGuid, static_cast<AppBar*>(this));
#endif
my_gui_object->guiobject_setRootWnd(this);
getScriptObject()->vcpu_setClassName(L"GuiObject");
getScriptObject()->vcpu_setController(WASABI_API_MAKI->maki_getController(guiObjectGuid));
cfg_reentry = 0;
xuihandle = newXuiHandle();
CreateXMLParameters(xuihandle);
}
void GuiObjectWnd::CreateXMLParameters(int master_handle)
{
int numParams = sizeof(params) / sizeof(params[0]);
hintNumberOfParams(xuihandle, numParams);
for (int i = 0;i < numParams;i++)
addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
}
GuiObjectWnd::~GuiObjectWnd()
{
WASABI_API_MAKI->maki_deencapsulate(guiObjectGuid, my_gui_object);
my_gui_object = NULL;
}
const wchar_t *GuiObjectWnd::getTip()
{
switch(wantTranslation())
{
case 1:
return _(tip);
case 2:
return __(tip);
default:
return tip;
}
}
int GuiObjectWnd::onRightButtonDown(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onRightButtonDown(x, y);
my_gui_object->guiobject_onRightButtonDown(x, y);
return 1;
}
int GuiObjectWnd::onRightButtonUp(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onRightButtonUp(x, y);
my_gui_object->guiobject_onRightButtonUp(x, y);
return 1;
}
int GuiObjectWnd::onLeftButtonDown(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onLeftButtonDown(x, y);
my_gui_object->guiobject_onLeftButtonDown(x, y);
return 1;
}
int GuiObjectWnd::onLeftButtonUp(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onLeftButtonUp(x, y);
my_gui_object->guiobject_onLeftButtonUp(x, y);
return 1;
}
int GuiObjectWnd::onMouseMove(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onMouseMove(x, y);
my_gui_object->guiobject_onMouseMove(x, y);
return 1;
}
int GuiObjectWnd::wantTranslation()
{
if (!my_gui_object) return 1;
return my_gui_object->guiobject_wantTranslation();
}
int GuiObjectWnd::onLeftButtonDblClk(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onLeftButtonDblClk(x, y);
my_gui_object->guiobject_onLeftButtonDblClk(x, y);
return 1;
}
int GuiObjectWnd::onRightButtonDblClk(int x, int y)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onRightButtonDblClk(x, y);
my_gui_object->guiobject_onRightButtonDblClk(x, y);
return 1;
}
// Martin> For the next two functions, we need to ensure that we don't kill volume change if nothing is done
int GuiObjectWnd::onMouseWheelDown (int click, int line)
{
if (!my_gui_object) return 1;
int ret = GUIOBJECTWND_PARENT::onMouseWheelDown(click, line);
if (!ret) ret = my_gui_object->guiobject_onMouseWheelDown(click, line);
return ret;
}
int GuiObjectWnd::onMouseWheelUp (int click, int line)
{
if (!my_gui_object) return 1;
int ret = GUIOBJECTWND_PARENT::onMouseWheelUp(click, line);
if (!ret) ret = my_gui_object->guiobject_onMouseWheelUp(click, line);
return ret;
}
int GuiObjectWnd::onResize()
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onResize();
if (!isInited()) return 1;
ifc_window *w = my_gui_object->guiobject_getRootWnd();
RECT r;
w->getClientRect(&r);
my_gui_object->guiobject_onResize(r.left, r.top, r.right - r.left, r.bottom - r.top);
return 1;
}
void GuiObjectWnd::onEnterArea()
{
if (!my_gui_object) return ;
GUIOBJECTWND_PARENT::onEnterArea();
my_gui_object->guiobject_onEnterArea();
}
void GuiObjectWnd::onLeaveArea()
{
if (!my_gui_object) return ;
GUIOBJECTWND_PARENT::onLeaveArea();
my_gui_object->guiobject_onLeaveArea();
}
void GuiObjectWnd::onSetVisible(int show)
{
if (!my_gui_object)
return ;
GUIOBJECTWND_PARENT::onSetVisible(show);
my_gui_object->guiobject_onSetVisible(show);
}
int GuiObjectWnd::onEnable(int en)
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onEnable(en);
my_gui_object->guiobject_onEnable(en);
return 1;
}
GuiObject *GuiObjectWnd::getGuiObject()
{
return my_gui_object;
}
RootObject *GuiObjectWnd::getRootObject()
{
return my_gui_object->guiobject_getRootObject();
}
int GuiObjectWnd::dragDrop(ifc_window *sourceWnd, int x, int y)
{
int r = DropTargetEnum::throwDrop(my_gui_object->guiobject_getDropTarget(), sourceWnd, x, y);
if (r == 0)
{
ifc_window *p = getParent();
if (p != NULL)
{
DragInterface *d = p->getDragInterface();
if (d != NULL)
return d->dragDrop(sourceWnd, x, y);
}
}
return r;
}
int GuiObjectWnd::dragEnter(ifc_window *sourceWnd)
{
my_gui_object->guiobject_dragEnter(sourceWnd);
return 1;
}
int GuiObjectWnd::dragOver(int x, int y, ifc_window *sourceWnd)
{
my_gui_object->guiobject_dragOver(x, y, sourceWnd);
return 1;
}
int GuiObjectWnd::dragLeave(ifc_window *sourceWnd)
{
my_gui_object->guiobject_dragLeave(sourceWnd);
return 1;
}
int GuiObjectWnd::onActivate()
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onActivate();
invalidate();
return 1;
}
int GuiObjectWnd::onDeactivate()
{
if (!my_gui_object) return 1;
GUIOBJECTWND_PARENT::onDeactivate();
invalidate();
return 1;
}
void GuiObjectWnd::onCancelCapture()
{
if (!my_gui_object) return ;
GUIOBJECTWND_PARENT::onCancelCapture();
my_gui_object->guiobject_onCancelCapture();
}
int GuiObjectWnd::setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *value)
{
if (_xuihandle == xuihandle)
{
switch (attrid)
{
case GUIOBJECT_FOCUSONCLICK:
setFocusOnClick(WTOI(value));
break;
default:
getGuiObject()->guiobject_setXmlParamById(attrid, value);
break;
}
}
return 0;
}
int GuiObjectWnd::onUnknownXmlParam(const wchar_t *param, const wchar_t *value)
{
return onUnknownXuiParam(param, value);
}
int GuiObjectWnd::setXmlParamById(int xmlhandle, int attrid, const wchar_t *name, const wchar_t *value)
{
return setXuiParam(xmlhandle, attrid, name, value);
}
void *GuiObjectWnd::getInterface(GUID interface_guid)
{
void *r = GUIOBJECTWND_PARENT::getInterface(interface_guid);
if (r) return r;
return getRootObject()->rootobject_getScriptObject()->vcpu_getInterface(interface_guid);
}
int GuiObjectWnd::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source)
{
#ifdef WASABI_COMPILE_CONFIG
if (!_wcsicmp(action, L"reload_config") && isInited())
{
if (cfg_reentry) return 1;
cfg_reentry = 1;
int r = onReloadConfig();
cfg_reentry = 0;
return r;
}
#endif
int rt = GUIOBJECTWND_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
getGuiObject()->guiobject_onAction(action, param, x, y, p1, p2, data, datalen, source);
return rt;
}
void GuiObjectWnd::setContent(const wchar_t *groupid_orguid, int autoresizefromcontent)
{
#ifdef WASABI_COMPILE_SKIN
// abstract_setAllowDeferredContent(0);
abstract_setContent(groupid_orguid, autoresizefromcontent);
#endif
}
void GuiObjectWnd::setContentBySkinItem(SkinItem *item, int autoresizefromcontent)
{
// abstract_setAllowDeferredContent(0);
#ifdef WASABI_COMPILE_SKIN
abstract_setContentBySkinItem(item, autoresizefromcontent);
#endif
}
void GuiObjectWnd::abstract_onNewContent()
{
#ifdef WASABI_COMPILE_SKIN
GUIOBJECTWND_PARENT::abstract_onNewContent();
#endif
onNewContent();
#ifdef WASABI_COMPILE_CONFIG
if (getGuiObject()->guiobject_hasCfgAttrib())
onReloadConfig();
#endif
}
GuiObject *GuiObjectWnd::findObject(const wchar_t *object_id)
{
return getGuiObject()->guiobject_findObject(object_id);
}
#ifdef WASABI_COMPILE_SCRIPT
ScriptObject *GuiObjectWnd::findScriptObject(const wchar_t *object_id)
{
GuiObject *fo = getGuiObject()->guiobject_findObject(object_id);
if (fo != NULL) return fo->guiobject_getScriptObject();
return NULL;
}
#endif
const wchar_t *GuiObjectWnd::getId()
{
if (my_gui_object)
return my_gui_object->guiobject_getId();
return GUIOBJECTWND_PARENT::getId();
}
int GuiObjectWnd::onPostOnInit()
{
int r = GUIOBJECTWND_PARENT::onPostOnInit();
#ifdef WASABI_COMPILE_CONFIG
if (getGuiObject()->guiobject_hasCfgAttrib())
onReloadConfig();
#endif
return r;
}
int GuiObjectWnd::onInit()
{
int r = GUIOBJECTWND_PARENT::onInit();
getGuiObject()->guiobject_onInit();
return r;
}
int GuiObjectWnd::onChar(unsigned int c)
{
if (!my_gui_object) return 1;
int r = GUIOBJECTWND_PARENT::onChar(c);
getGuiObject()->guiobject_onChar(c);
return r;
}
int GuiObjectWnd::onKeyDown(int vkcode)
{
if (!my_gui_object) return 1;
int r = GUIOBJECTWND_PARENT::onKeyDown(vkcode);
getGuiObject()->guiobject_onKeyDown(vkcode);
return r;
}
int GuiObjectWnd::onKeyUp(int vkcode)
{
if (!my_gui_object) return 1;
int r = GUIOBJECTWND_PARENT::onKeyUp(vkcode);
getGuiObject()->guiobject_onKeyUp(vkcode);
return r;
}
int GuiObjectWnd::onGetFocus()
{
if (!my_gui_object) return 1;
int r = GUIOBJECTWND_PARENT::onGetFocus();
getGuiObject()->guiobject_onGetFocus();
return r;
}
int GuiObjectWnd::onKillFocus()
{
if (!my_gui_object) return 1;
int r = GUIOBJECTWND_PARENT::onKillFocus();
getGuiObject()->guiobject_onKillFocus();
return r;
}
int GuiObjectWnd::onAcceleratorEvent(const wchar_t *name)
{
int r = GUIOBJECTWND_PARENT::onAcceleratorEvent(name);
getGuiObject()->guiobject_onAccelerator(name);
return r;
}
int GuiObjectWnd::wantFocus()
{
if (GUIOBJECTWND_PARENT::wantFocus()) return 1;
if (my_gui_object)
return my_gui_object->guiobject_wantFocus();
return 0;
}
+237
View File
@@ -0,0 +1,237 @@
#ifndef __GUIOBJWND_H
#define __GUIOBJWND_H
#if defined(WIN32) || defined(WIN64)
#define USEAPPBAR
#endif
#ifdef USEAPPBAR
#include <api/wnd/wndclass/appbarwnd.h>
#define GUIOBJECTWND_PARENT AppBarWnd
#else
#include <api/wnd/wndclass/clickwnd.h>
#define GUIOBJECTWND_PARENT ClickWnd
#endif
#include <api/script/scriptobj.h>
#include <api/script/objects/guiobject.h>
#include <api/script/objects/rootobj.h>
#include <api/skin/xmlobject.h>
#include <api/service/svcs/svc_xuiobject.h>
// {E5760861-5489-4ffc-BE02-061D9DA6CD1B}
const GUID guiObjectWndGuid =
{ 0xe5760861, 0x5489, 0x4ffc, { 0xbe, 0x2, 0x6, 0x1d, 0x9d, 0xa6, 0xcd, 0x1b } };
#define XUI_ATTRIBUTE_IMPLIED XML_ATTRIBUTE_IMPLIED
#define XUI_ATTRIBUTE_REQUIRED XML_ATTRIBUTE_REQUIRED
class GuiObjectWnd : public GUIOBJECTWND_PARENT, public RootObjectInstance, public XmlObjectI
{
public:
GuiObjectWnd();
virtual ~GuiObjectWnd();
#ifdef WASABI_COMPILE_CONFIG
virtual int onReloadConfig() { return 1; }
#endif
// XmlObject
virtual int setXmlParamById(int xmlhandle, int attrid, const wchar_t *name, const wchar_t *value);
virtual int onUnknownXmlParam(const wchar_t *param, const wchar_t *value);
virtual int newXuiHandle() { return newXmlHandle(); }
// ClickWnd
virtual int onRightButtonDown(int x, int y);
virtual int onRightButtonUp(int x, int y);
virtual int onLeftButtonDown(int x, int y);
virtual int onLeftButtonUp(int x, int y);
virtual int onMouseMove(int x, int y);
virtual int onLeftButtonDblClk(int x, int y);
virtual int onRightButtonDblClk(int x, int y);
virtual int onMouseWheelUp(int click, int lines);
virtual int onMouseWheelDown(int click, int lines);
virtual int onResize();
virtual int onActivate();
virtual int onDeactivate();
virtual void onEnterArea();
virtual void onLeaveArea();
virtual void onSetVisible(int show);
virtual int onEnable(int en);
virtual void onCancelCapture();
virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
virtual int acceptExternalDrops() { return 1; }
virtual int dragEnter(ifc_window *sourceWnd);
virtual int dragOver(int x, int y, ifc_window *sourceWnd);
virtual int dragLeave(ifc_window *sourceWnd);
virtual void *getInterface(GUID g);
virtual int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
virtual const wchar_t *getId();
virtual int onAcceleratorEvent(const wchar_t *name);
virtual void setContent(const wchar_t *groupid_orguid, int autoresizefromcontent = 0);
virtual void setContentBySkinItem(SkinItem *item, int autoresizefromcontent = 0);
virtual void onNewContent() {}
// AbstractWndHolder
virtual void abstract_onNewContent();
virtual int onUnknownXuiParam(const wchar_t *param, const wchar_t *value) { return 0; }
virtual GuiObject *findObject(const wchar_t *object_id);
#ifdef WASABI_COMPILE_SCRIPT
virtual ScriptObject *findScriptObject(const wchar_t *object_id);
#endif
#ifdef WASABI_COMPILE_SKIN
virtual GuiObject *getContent() { return abstract_getContent(); }
virtual ScriptObject *getContentScriptObject() { return abstract_getContentScriptObject(); }
virtual ifc_window *getContentRootWnd() { return abstract_getContentRootWnd(); }
#endif
// BaseWnd
virtual int onInit();
virtual int onPostOnInit();
virtual int onChar(unsigned int c);
virtual int onKeyDown(int vkcode);
virtual int onKeyUp(int vkcode);
virtual int onGetFocus();
virtual int onKillFocus();
virtual int wantFocus();
const wchar_t *getTip();
// GuiObjectWnd
int wantTranslation();
GuiObject *getGuiObject();
RootObject *getRootObject();
int cfg_reentry;
// XuiObject
virtual int setXuiParam(int _xuihandle, int attrid, const wchar_t *name, const wchar_t *value);
protected:
/*static */void CreateXMLParameters(int master_handle);
private:
GuiObject *my_gui_object;
int xuihandle;
static XMLParamPair params[];
public:
enum {
GUIOBJECT_ID = 0,
GUIOBJECT_ALPHA,
GUIOBJECT_ACTIVEALPHA,
GUIOBJECT_INACTIVEALPHA,
GUIOBJECT_SYSREGION,
GUIOBJECT_RECTRGN,
GUIOBJECT_TOOLTIP,
GUIOBJECT_SYSMETRICSX,
GUIOBJECT_SYSMETRICSY,
GUIOBJECT_SYSMETRICSW,
GUIOBJECT_SYSMETRICSH,
GUIOBJECT_MOVE,
GUIOBJECT_RENDERBASETEXTURE,
GUIOBJECT_CFGATTR,
GUIOBJECT_X,
GUIOBJECT_Y,
GUIOBJECT_W,
GUIOBJECT_H,
GUIOBJECT_VISIBLE,
GUIOBJECT_ENABLED,
GUIOBJECT_RELATX,
GUIOBJECT_RELATY,
GUIOBJECT_RELATW,
GUIOBJECT_RELATH,
GUIOBJECT_DROPTARGET,
GUIOBJECT_GHOST,
GUIOBJECT_NOTIFY,
GUIOBJECT_FOCUSONCLICK,
GUIOBJECT_TABORDER,
GUIOBJECT_WANTFOCUS,
GUIOBJECT_SETNODBLCLICK,
GUIOBJECT_SETNOLEFTCLICK,
GUIOBJECT_SETNORIGHTCLICK,
GUIOBJECT_SETNOMOUSEMOVE,
GUIOBJECT_SETNOCONTEXTMENU,
GUIOBJECT_SETX1,
GUIOBJECT_SETY1,
GUIOBJECT_SETX2,
GUIOBJECT_SETY2,
GUIOBJECT_SETANCHOR,
GUIOBJECT_SETCURSOR,
GUIOBJECT_FITTOPARENT,
GUIOBJECT_USERDATA,
#ifdef USEAPPBAR
GUIOBJECT_APPBAR,
#endif
GUIOBJECT_TRANSLATE,
GUIOBJECT_NUMPARAMS
};
};
template <class T, const wchar_t XMLTAG[], char SVCNAME[]>
class XuiObjectSvc : public svc_xuiObjectI
{
public:
static const wchar_t *xuisvc_getXmlTag() { return XMLTAG; }
int testTag(const wchar_t *xmltag)
{
if (!WCSICMP(xmltag, XMLTAG)) return 1;
return 0;
}
GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params = NULL)
{
if (testTag(xmltag))
{
T * obj = new T;
ASSERT(obj != NULL);
return obj->getGuiObject();
}
return NULL;
}
void destroy(GuiObject *g)
{
T *obj = static_cast<T *>(g->guiobject_getRootWnd());
delete obj;
}
static const char *getServiceName() { return SVCNAME; }
};
template <class T>
class XuiObjectSvc2 : public svc_xuiObjectI
{
public:
static const wchar_t *xuisvc_getXmlTag() { return T::xuiobject_getXmlTag(); }
int testTag(const wchar_t *xmltag)
{
if (!WCSICMP(xmltag, T::xuiobject_getXmlTag())) return 1;
return 0;
}
GuiObject *instantiate(const wchar_t *xmltag, ifc_xmlreaderparams *params = NULL)
{
if (testTag(xmltag))
{
T * obj = new T;
ASSERT(obj != NULL);
return obj->getGuiObject();
}
return NULL;
}
void destroy(GuiObject *g)
{
T *obj = static_cast<T *>(g->guiobject_getRootWnd());
delete obj;
}
static const char *getServiceName() { return T::xuiobject_getServiceName(); }
};
#endif
+286
View File
@@ -0,0 +1,286 @@
#include "precomp.h"
#include "itemlistwnd.h"
#include "../../common/metatags.h"
#include "../../studio/api.h"
#include "../skinclr.h"
#include "../../common/filename.h"
#include "../../common/dragitemi.h"
#include "../../common/contextmenu.h"
#define NIFTY_OUTLINE
static SkinColor current("wasabi.itemlist.outline.current");
static SkinColor selborder("wasabi.itemlist.selborder");
static SkinColor focus("wasabi.itemlist.outline.focus");
ItemListColumn_MetaTag::ItemListColumn_MetaTag(const char *newtag, int centered, const char *label)
: ItemListColumn() {
if (label == NULL) label = newtag;
setLabel(label);
tag = newtag;
center = centered;
datatype = api->metadb_getMetaDataType(tag);
}
ItemListColumn_Callback::ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const char *name)
: ItemListColumn(name)
{
parent = _parent;
lparam = _lparam;
}
void ItemListColumn_Callback::render(int pos, const char *playstring, Canvas &c, RECT &r) {
parent->userRender(pos, playstring, c, r, lparam);
}
void ItemListColumn_Callback::columnToText(int pos, const char *playstring, char *str, int maxlen) {
parent->userColumnToText(pos, playstring, lparam, str, maxlen);
}
void ItemListColumn_MetaTag::render(int pos, const char *playstring, Canvas &canvas, RECT &r) {
char buf[4096]="";
if (api->metadb_getMetaData(playstring, tag, buf, 4096) <= 1) return;
api->metadb_renderData(&canvas, r, buf, datatype, center);
}
void ItemListColumn_MetaTag::columnToText(int pos, const char *playstring, char *str, int maxlen) {
api->metadb_getMetaData(playstring, tag, str, maxlen);
}
const char *ItemListColumn_MetaTag::getTag() {
return tag;
}
void ItemListColumn_Numbered::render(int pos, const char *playstring, Canvas &c, RECT &r) {
StringPrintf buf("%d.", pos+1);
c.textOutEllipsed(r.left, r.top, r.right - r.left, r.bottom-r.top, buf);
}
void ItemListColumn_Numbered::columnToText(int pos, const char *playstring, char *str, int maxlen) {
StringPrintf buf("%d", pos+1);
STRNCPY(str, buf, maxlen);
}
ItemListWnd::ItemListWnd() {
keep = NULL;
item_invalidate_border++;
}
ItemListWnd::~ItemListWnd() {
api->syscb_deregisterCallback(static_cast<MetaCallbackI *>(this));
}
int ItemListWnd::onInit() {
ITEMLISTWND_PARENT::onInit();
api->syscb_registerCallback(static_cast<MetaCallbackI *>(this));
return 1;
}
int ItemListWnd::insertColumn(ItemListColumn *column, int width, int pos) {
column->setWidth(width);
return ITEMLISTWND_PARENT::insertColumn(column, pos);
}
int ItemListWnd::onBeginDrag(int iItem) {
if (!wantAutoDrag()) return ITEMLISTWND_PARENT::onBeginDrag(iItem);
// add all the entries
int n, i, c = 0;
n = getNumItems();
if (n == 0) return 0; // empty list
ASSERT(keep == NULL);
keep = new PtrList<FilenameNC>();
// count up the items
for (i = 0; i < n; i++) {
if (getItemSelected(i)) { // expose all the pointers we can
LPARAM lparam = getItemData(i);
if (!addMoreDragTypes(i)) {
FilenameNC *fn = keep->addItem(new FilenameNC(convertlParam(lparam)));
addDragItem(DD_FILENAME, static_cast<Filename*>(fn));
}
c++;
}
}
if (keep->getNumItems() == 0 || c <= 0) {
delete keep; keep = NULL;
return 0;
}
handleDrag();
return 1;
}
int ItemListWnd::dragComplete(int success) {
ASSERT(keep != NULL);
keep->deleteAll();
delete keep; keep = NULL;
return 1;
}
int ItemListWnd::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) {
const char *playstring = convertlParam(lParam);
if (playstring == NULL) return 0;
COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam);
COLORREF fgcolor = getTextColor(lParam);
int iscur = getSelected(lParam);
RECT box;
canvas->getClipBox(&box);
if (!getBgBitmap()) {
RECT r2 = *r;
r2.left = box.left;
RegionI *reg = new RegionI(&r2);
canvas->selectClipRgn(reg);
delete reg;
canvas->fillRect(r, getBgColor());
}
canvas->setTextColor(fgcolor);
// ASSERT(cols.getNumItems() == getNumColumns());
if (isselected) {
RECT mr = *r;
canvas->fillRect(&mr, bgcolor);
/*au gratin potatoes/broccoli
chicken^2
salad, croutons, cheese, ranch
fries */
#ifdef NIFTY_OUTLINE
int prevsel = getItemSelected(pos-1);
int nextsel = getItemSelected(pos+1);
mr.bottom--;
canvas->pushPen(selborder);
canvas->lineDraw(mr.left, mr.top, mr.left, mr.bottom);
canvas->lineDraw(mr.right-1, mr.top, mr.right-1, mr.bottom);
if (!prevsel) canvas->lineDraw(mr.left, mr.top, mr.right, mr.top);
if (!nextsel) canvas->lineDraw(mr.left, mr.bottom, mr.right, mr.bottom);
canvas->popPen();
#endif
}
if (isfocused || iscur) {
int pentype = isfocused ? FALSE : TRUE;
int boxcolor = iscur ? current : focus;
canvas->drawRect(r, pentype, boxcolor);
}
canvas->pushTextSize(getFontSize());
int x = 1+r->left;
for (int i = 0; i < getNumColumns(); i++) {
ItemListColumn *col = (ItemListColumn *)enumListColumn(i);
RECT ir;
ir.left = x;
ir.right = x + getColumnWidth(i);
ir.top = r->top;
ir.bottom = r->bottom;
if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) {
col->render(pos, playstring, *canvas, ir);
}
x = ir.right;
}
canvas->popTextSize();
return 1;
}
void ItemListWnd::convertlParamColumn(int col, int pos, LPARAM param, char *str, int maxlen) {
ASSERT(str != NULL);
ItemListColumn *cl = (ItemListColumn *)enumListColumn(col);
const char *playstring = convertlParam(param);
cl->columnToText(pos, playstring, str, maxlen);
}
int ItemListWnd::onContextMenu(int x, int y) {
PtrList<FilenameNC> filenames;
DragItemI *dragitem = NULL;
if ((dragitem = itemlistwnd_getDragItem(x, y)) == NULL) {
DragItemT<Filename> *di = new DragItemT<Filename>;
int n = getNumItems();
for (int i = 0; i < n; i++) {
if (getItemSelected(i)) {
LPARAM lparam = getItemData(i);
const char *playstring = convertlParam(lparam);
di->addDatum(filenames.addItem(new FilenameNC(playstring)));
}
}
dragitem = di;
}
ContextMenu cm(this, filenames.getNumItems() ? dragitem : NULL, false);
PtrList<DragItemI> drags;
for (int i = 0; ; i++) {
DragItemI *aitem = itemlistwnd_getSecondDragItem(i);
if (aitem == NULL) break;
drags.addItem(aitem);
if (cm.getNumCommands()) cm.addSeparator();
cm.addDragItem(aitem);
}
itemlistwnd_addCustomContextMenuCommands(&cm);
int r = cm.popAtMouse();
if (r < -10) itemlistwnd_contextMenuResult(r);
drags.deleteAll();
filenames.deleteAll();
delete dragitem;
return 1;
}
#if 0
int ItemListWnd::onRightClick(int itemnum, int _x, int _y) {
// figure out which column they clicked on
int x, l = 0, r = 0;
for (int i = 0; i < cols.getNumItems(); i++) {
l = r;
r += getColumnWidth(i);
if (_x >= l && y <= r) break;
}
if (i >= cols.getNumItems()) return 0;
PlayItem *item = convertlParam(itemnum);
if (!allowEdition(item, cols[i]->getTag())) return 0;
return 0;
}
#endif
void ItemListWnd::metacb_onItemChange(const char *playstring, const char *tag) {
int n = getNumItems();
for (int i = 0; i < n; i++) {
const char *ps = convertlParam(getItemData(i));
if (ps != NULL && STREQL(ps, playstring)) {
onItemChange(i, ps);
invalidateItem(i);
}
}
}
void ItemListWnd::metacb_onItemDel(const char *playstring) {
int n = getNumItems();
for (int i = 0; i < n; i++) {
const char *ps = convertlParam(getItemData(i));
if (ps != NULL && STREQL(ps, playstring)) {
onItemDel(i, ps);
invalidateItem(i);
}
}
}
+426
View File
@@ -0,0 +1,426 @@
//PORTABLE
#ifndef _ITEMLIST_H
#define _ITEMLIST_H
#include "listwnd.h"
#include "../canvas.h"
#include "../named.h"
#include "../ptrlist.h"
#include "../string.h"
#include "../../studio/metacb.h"
class FilenameNC;
class DragItemI;
class ContextMenu;
// this class just handles rendering the various properties of playitems
// in a listwnd... the rest is up to you, just override the convert fn
// abstract base class to render something in a column for a playstring
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class NOVTABLE ItemListColumn : public ListColumn {
protected:
/**
Method
@see
@ret
@param
*/
ItemListColumn(const wchar_t *name=NULL) : ListColumn(name) {}
public:
/**
Method
@see
@ret
@param
*/
virtual ~ItemListColumn() {}
/**
Method
@see
@ret
@param
*/
virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r)=0;
/**
Method
@see
@ret
@param
*/
virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen)=0;
};
#define ITEMLISTWND_PARENT ListWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ItemListWnd : public ListWnd, private MetaCallbackI {
friend class ItemListColumn_Callback;
public:
/**
Method
@see
@ret
@param
*/
ItemListWnd();
/**
Method
@see
@ret
@param
*/
virtual ~ItemListWnd();
/**
Method
@see
@ret
@param
*/
virtual int onInit();
/**
Method
@see
@ret
@param
*/
int insertColumn(ItemListColumn *column, int width, int pos=-1);
protected:
// override and return 0 to suppress auto-dragging from window
/**
Method
@see
@ret
@param
*/
virtual int wantAutoDrag() { return 1; }
// handles auto-adding all selected rows and calls addDragTypes
// so you can add more via addDragItem()
/**
Method
@see
@ret
@param
*/
virtual int onBeginDrag(int);
// if you return 0, the Filename version will be auto-added, otherwise not
/**
Method
@see
@ret
@param
*/
virtual int addMoreDragTypes(int pos) { return 0; }
/**
Method
@see
@ret
@param
*/
virtual int dragComplete(int success);
// tell ListWnd we do our own drawing
/**
Method
@see
@ret
@param
*/
virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused);
// ItemListColumn_Callback calls this to do its rendering, lParam is what you
// gave it to pass back to you
/**
Method
@see
@ret
@param
*/
virtual void userRender(int pos, const wchar_t *playstring, Canvas &c, RECT &r, LPARAM lParam) {}
// ItemListColumn_Callback calls this to get the column text, lParam is what you
// gave it to pass back to you
/**
Method
@see
@ret
@param
*/
virtual void userColumnToText(int pos, const wchar_t *playstring, LPARAM lParam, wchar_t *str, int maxlen) {}
// override this to turn the ownerdraw into a playstring
virtual const wchar_t *convertlParam(LPARAM lParam)=0;
virtual void convertlParamColumn(int col, int pos, LPARAM lParam, wchar_t *str, int maxlen);
// override this and return 1 if you want a "current" box around item
/**
Method
@see
@ret
@param
*/
virtual int getSelected(LPARAM lParam) { return 0; }
// virtual int onRightClick(int itemnum, int x, int y);
// automatically generated context menu (uses Filename)
/**
Method
@see
@ret
@param
*/
virtual int onContextMenu(int x, int y);
// return optional DragItemI for context menu (will be deleted for you)
virtual DragItemI *itemlistwnd_getDragItem(int x, int y) { return NULL; }
virtual DragItemI *itemlistwnd_getSecondDragItem(int n) { return NULL; }
virtual void itemlistwnd_addCustomContextMenuCommands(ContextMenu *cm) { }
virtual void itemlistwnd_contextMenuResult(int res) { }
// return TRUE if it's ok to edit in place
/**
Method
@see
@ret
@param
*/
virtual int allowEdition(const wchar_t *playstring, wchar_t *field) { return 0; }
/**
Method
@see
@ret
@param
*/
virtual void resort() {
//TODO> implement me!
}
protected:
// implement this if you want to know when an item's metadata changed
/**
Method
@see
@ret
@param
*/
virtual void onItemChange(int pos, const wchar_t *playstring) { }
/**
Method
@see
@ret
@param
*/
virtual void onItemDel(int pos, const wchar_t *playstring) { }
/**
Method
@see
@ret
@param
*/
virtual void metacb_onItemChange(const wchar_t *playstring, const wchar_t *tag);
/**
Method
@see
@ret
@param
*/
virtual void metacb_onItemDel(const wchar_t *);
private:
PtrList<FilenameNC> *keep;
};
// column class to ask ItemListWnd to do the rendering
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ItemListColumn_Callback : public ItemListColumn {
public:
/**
Method
@see
@ret
@param
*/
ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const wchar_t *name=NULL);
/**
Method
@see
@ret
@param
*/
virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
private:
ItemListWnd *parent;
LPARAM lparam;
};
// column class to render a metatag
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ItemListColumn_MetaTag : public ItemListColumn {
public:
/**
Method
@see
@ret
@param
*/
ItemListColumn_MetaTag(const wchar_t *tag, int center=0, const wchar_t *label=NULL);
/**
Method
@see
@ret
@param
*/
virtual ~ItemListColumn_MetaTag() {}
/**
Method
@see
@ret
@param
*/
virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
const wchar_t *getTag();
private:
StringW tag;
int center;
int datatype;
};
// this just renders the position of the item, starting from 1
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ItemListColumn_Numbered : public ItemListColumn {
public:
/**
Method
@see
@ret
@param
*/
ItemListColumn_Numbered(int _offset=0) : offset(_offset) {}
/**
Method
@see
@ret
@param
*/
virtual void render(int pos, const wchar_t *playstring, Canvas &c, RECT &r);
virtual void columnToText(int pos, const wchar_t *playstring, wchar_t *str, int maxlen);
private:
int offset;
};
#endif
+203
View File
@@ -0,0 +1,203 @@
#include <precomp.h>
#include "labelwnd.h"
#include <api/locales/xlatstr.h>
#include <api/wnd/paintsets.h>
#include <tataki/canvas/bltcanvas.h>
#include <tataki/color/skinclr.h>
#include <api/wnd/notifmsg.h>
#include <tataki/region/region.h>
#include <api/wnd/PaintCanvas.h>
static SkinColor labelfg(L"wasabi.labelwnd.foreground");
static SkinColor labelbg(L"wasabi.labelwnd.background", L"Text backgrounds");
#define DEF_LABEL_HEIGHT 0
#define DEF_LABEL_FONTSIZE 16
LabelWnd::LabelWnd() {
show_label = FALSE;
labelsize = DEF_LABEL_FONTSIZE;
labelHeight = 0;
margin=0;
setVirtual(0);
}
void LabelWnd::getClientRect(RECT *r) {
LABELWND_PARENT::getClientRect(r);
r->top += getLabelHeight();
}
int LabelWnd::onResize() {
LABELWND_PARENT::onResize();
invalidateLabel();
/* if (getLabelHeight() <= 0) return 0;
RECT r,ir;
LABELWND_PARENT::getClientRect(&r);
LABELWND_PARENT::getNonClientRect(&ir);
ir.bottom = ir.top + getLabelHeight()+margin;
invalidateRect(&ir);*/
return 1;
}
int LabelWnd::onPaint(Canvas *canvas) {
if (getLabelHeight() <= 0) return LABELWND_PARENT::onPaint(canvas);
PaintBltCanvas paintcanvas;
if (canvas == NULL) {
if (!paintcanvas.beginPaintNC(this)) return 0;
canvas = &paintcanvas;
}
RECT r;
LabelWnd::getNonClientRect(&r);
if (canvas->isFixedCoords()) { // handle possible double buffer
// convert to canvas coords
r.right -= r.left; r.left = 0;
r.bottom -= r.top; r.top = 0;
}
r.bottom = r.top + getLabelHeight();
if (margin) {
r.left+=margin;
r.right-=margin;
r.bottom+=margin*2;
}
LABELWND_PARENT::onPaint(canvas);
int got_focus = gotFocus() || forceFocus();
if (wantRenderBaseTexture()) {
WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), canvas, r, this);
}
#ifdef WASABI_COMPILE_PAINTSETS
WASABI_API_WND->paintset_render(Paintset::LABEL, canvas, &r, got_focus ? 255 : 64);
#endif
Wasabi::FontInfo fontInfo;
fontInfo.opaque=false;
fontInfo.pointSize = getLabelHeight()-1;
const wchar_t *name = getName();
if (name == NULL || *name == '\0')
name = L"Label";
#define LEFTMARGIN 3
fontInfo.color = labelbg;
const wchar_t *xname = name;
switch(wantTranslation())
{
case 1:
xname = _(name);
break;
case 2:
xname = __(name);
break;
}
canvas->textOut(r.left+LEFTMARGIN+1, r.top+1, xname, &fontInfo);
fontInfo.color = labelfg;
canvas->textOut(r.left+LEFTMARGIN, r.top, xname, &fontInfo);
return 1;
}
void LabelWnd::onSetName() {
LABELWND_PARENT::onSetName();
// make sure label gets repainted
if (isInited()) {
RECT r;
LabelWnd::getNonClientRect(&r);
r.bottom = r.top + getLabelHeight();
invalidateRect(&r);
}
}
//CUTint LabelWnd::childNotify(api_window *child, int msg, intptr_t param1, intptr_t param2) {
//CUT switch (msg) {
//CUT case CHILD_WINDOWSHADE_CAPABLE: return show_label;
//CUT case CHILD_WINDOWSHADE_ENABLE: return TRUE;
//CUT }
//CUT return LABELWND_PARENT::childNotify(child, msg, param1, param2);
//CUT}
int LabelWnd::showLabel(int show) {
show_label = show;
setFontSize(-1);
if (isPostOnInit()) {
onResize();
}
return 1;
}
int LabelWnd::getLabelHeight() {
return show_label ? labelHeight : 0;
}
void LabelWnd::setMargin(int newmargin) {
margin = newmargin;
RECT r;
getNonClientRect(&r);
r.bottom = getLabelHeight()+margin;
invalidateRect(&r);
}
int LabelWnd::onGetFocus() {
LABELWND_PARENT::onGetFocus();
invalidateLabel();
return 1;
}
int LabelWnd::onKillFocus() {
LABELWND_PARENT::onKillFocus();
invalidateLabel();
return 1;
}
void LabelWnd::invalidateLabel() {
if (labelHeight <= 0) return;
RECT ncr;
RECT cr;
// RECT lr;
LabelWnd::getNonClientRect(&ncr);
LabelWnd::getClientRect(&cr);
RegionI nonClientRgn(&ncr);
RegionI clientRgn(&cr);
nonClientRgn.subtractRgn(&clientRgn);
invalidateRgn(&nonClientRgn);
// SubtractRect(&lr, &ncr, &cr); // PORT ME
// invalidateRect(&lr);
}
int LabelWnd::wantFocus() {
return (labelHeight > 0);
}
void LabelWnd::reloadResources()
{
LABELWND_PARENT::reloadResources();
if (isPostOnInit())
onResize();
invalidateLabel();
}
int LabelWnd::setFontSize(int size)
{
LABELWND_PARENT::setFontSize(size);
TextInfoCanvas blt(this);
Wasabi::FontInfo fontInfo;
#ifndef WASABINOMAINAPI
fontInfo.pointSize = labelsize+api->metrics_getDelta();
#else
fontInfo.pointSize = labelsize;
//MULTIAPI-FIXME: not handling delta
#endif
labelHeight = blt.getTextHeight(&fontInfo) + 1;
invalidate();
if (isPostOnInit()) onResize();
return 1;
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef _LABELWND_H
#define _LABELWND_H
#include <bfc/common.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#define LABELWND_PARENT GuiObjectWnd
class LabelWnd : public LABELWND_PARENT {
protected:
LabelWnd();
public:
virtual void getClientRect(RECT *);
virtual int onResize();
virtual int onPaint(Canvas *canvas);
virtual int onGetFocus();
virtual int onKillFocus();
virtual void invalidateLabel();
virtual int wantFocus();
virtual int wantRenderBaseTexture() { return 1; }
// override & return 1 to force painting label with focus all the time
virtual int forceFocus() { return 0; }
virtual void onSetName();
virtual void setMargin(int newmargin);
virtual int setFontSize(int size);
//CUT virtual int childNotify(api_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
int showLabel(int show);
int getLabelHeight();
void reloadResources();
private:
int show_label, labelsize;
int labelHeight;
int margin;
};
// use this if you want a generic labelwnd (but try not to)
class LabelWndI : public LabelWnd { };
#endif
File diff suppressed because it is too large Load Diff
+459
View File
@@ -0,0 +1,459 @@
#ifndef _LISTWND_H
#define _LISTWND_H
#include <api/wnd/wndclass/scbkgwnd.h>
#include <bfc/common.h>
#include <bfc/freelist.h>
#include "SelItemList.h"
#define POS_LAST -1
#define LISTWND_PARENT ScrlBkgWnd
#define LW_HT_DONTKNOW (-1)
#define LW_HT_ABOVE (-10)
#define LW_HT_BELOW (-20)
#define COL_LEFTALIGN 0
#define COL_CENTERALIGN 1
#define COL_RIGHTALIGN 2
class listItem;
class ListWnd;
class CompareListItem;
class ListColumn : public NamedW
{
friend class ListWnd;
public:
ListColumn(const wchar_t *name=NULL, int isdynamic=FALSE);
virtual ~ListColumn() { }
int getWidth();
void setWidth(int newwidth);
const wchar_t *getLabel();
void setLabel(const wchar_t *newlabel);
virtual int customDrawHeader(Canvas *c, RECT *cr, const Wasabi::FontInfo *fontInfo);
virtual int onHeaderClick() { return 0; }//return 1 if you override
virtual int onColumnLeftClick(int pos) { return 0; }//return 1 if you override
int getNumeric() { return numeric; }
void setDynamic(int isdynamic);
int isDynamic() { return dynamic; }
void setAlignment(int _align) { align = _align; }
int getAlignment() { return align; }
protected:
void setIndex(int i);
int getIndex();
void setList(ListWnd *list);
ListWnd *getList();
void setNumeric(int n) { numeric=n; }
private:
int width;
int index;
int numeric;
int dynamic;
ListWnd *list;
int align;
};
//class SelItemList;
class ListWnd : public ScrlBkgWnd
{
friend class ListColumn;
friend class SelItemList;
public:
ListWnd();
virtual ~ListWnd();
virtual int onInit();
virtual int onPostOnInit();
virtual int onPaint(Canvas *canvas);
virtual int onResize();
virtual int onLeftButtonDown(int x, int y);
virtual int onLeftButtonUp(int x, int y);
virtual int onRightButtonDown(int x, int y);
virtual int onRightButtonUp(int x, int y);
virtual int onMouseMove(int x, int y);
virtual int onLeftButtonDblClk(int x, int y);
virtual int onChar(unsigned int c);
virtual int onKeyDown(int keyCode);
virtual int onContextMenu (int x, int y);
virtual int wantAutoContextMenu();
virtual int onMouseWheelUp(int click, int lines);
virtual int onMouseWheelDown(int click, int lines);
virtual int wantAutoDeselect() { return wantautodeselect; }
virtual void setWantAutoDeselect(int want) { wantautodeselect = want; }
void onSetVisible(int show);
void setAutoSort(bool dosort);
void setOwnerDraw(bool doownerdraw);
virtual void timerCallback(int id);
void next(int wantcb=1);
void selectCurrent();
void selectFirstEntry(int wantcb=1);
void previous(int wantcb=1);
void pagedown(int wantcb=1);
void pageup(int wantcb=1);
void home(int wantcb=1);
void end(int wantcb=1);
void setItemCount(int c);
void reset();
void setShowColumnsHeaders(int show);
int addColumn(const wchar_t *name, int width, int numeric=0, int align=COL_LEFTALIGN); // adds to end
ListColumn *getColumn(int n);
int getNumColumns();
int getColumnWidth(int col);
bool setRedraw(bool redraw); // returns prev state
bool getRedraw();
void setMinimumSize(int size);
virtual int addItem(const wchar_t *label, LPARAM lParam);
virtual int insertItem(int pos, const wchar_t *label, LPARAM lParam);
virtual int getLastAddedItemPos();
virtual void setSubItem(int pos, int subpos, const wchar_t *txt);
virtual void deleteAllItems();
virtual int deleteByPos(int pos);
int getNumItems(void);
virtual int getItemLabel(int pos, int subpos, wchar_t *text, int textmax);
virtual void setItemLabel(int pos, const wchar_t *text);
virtual LPARAM getItemData(int pos);
virtual int getItemRect(int pos, RECT *r);
virtual int getItemSelected(int pos); // returns 1 if selected
virtual int getItemFocused(int pos); // returns 1 if focused
virtual int getItemFocused(); // returns focused item
void setItemFocused(int pos, int ensure_visible=TRUE);
void ensureItemVisible(int pos);
void invalidateColumns();
virtual int scrollAbsolute(int x);
virtual int scrollRelative(int x);
virtual void scrollLeft(int lines=1);
virtual void scrollRight(int lines=1);
virtual void scrollUp(int lines=1);
virtual void scrollDown(int lines=1);
virtual const wchar_t *getSubitemText(int pos, int subpos);
int getFirstItemSelected();
int getNextItemSelected(int lastpos); // next item AFTER given pos
virtual int selectAll(int cb=1); // force all items selected
virtual int deselectAll(int cb=1); // force all items to be deselected
virtual int invertSelection(int cb=1); // invert all selections
virtual int hitTest(POINT pos, int drag=0);
/**
Method
@see
@ret
*/
virtual int hitTest(int x, int y, int drag=0);
/**
Method
@see
@ret
*/
virtual int invalidateItem(int pos);
virtual int locateData(LPARAM data);
// -1 if we've never been drawn yet
/**
Method
@see
@ret
*/
int getFirstItemVisible() const { return firstItemVisible; }
/**
Method
@see
@ret
*/
int getLastItemVisible() const { return lastItemVisible; }
virtual int setFontSize(int size);
virtual int getFontSize();
virtual void jumpToNext(wchar_t c);
int wantFocus() { return 1; }
void scrollToItem(int pos);
virtual void resort();
int getSortDirection();
/**
Method
@see
@ret
*/
int getSortColumn();
void setSortColumn(int col);
void setSortDirection(int dir);
int findItemByParam(LPARAM param);
void setItemParam(int pos, LPARAM param);
int getItemCount() { return getNumItems(); }
void setSelectionStart(int pos, int wantcb=1);
/**
Method
@see
@ret
*/
virtual void setSelectionEnd(int pos);
void setSelected(int pos, int selected, int cb=1);
void toggleSelection(int pos, int setfocus=TRUE, int cb=1);
virtual int getHeaderHeight();
// this sort function just provides string/numeric comparison
// if you need more types, just override and provide your own
virtual int sortCompareItem(listItem *p1, listItem *p2);
int getPreventMultipleSelection() { return preventMultipleSelection; }
int setPreventMultipleSelection(int val) { return preventMultipleSelection = val; }
void moveItem(int from, int to);
virtual int onAcceleratorEvent(const wchar_t *name);
// override this to turn the LPARAM into a text
virtual const wchar_t *convertlParam(LPARAM lParam) { return NULL; }
virtual void convertlParamColumn(int col, int pos, LPARAM param, wchar_t *str, int maxlen) { };
protected:
/*static */void CreateXMLParameters(int master_handle);
// return 1 if you override this
virtual int ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { return 0; };
virtual void onPreItemDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { }
virtual void onPostItemDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int selected, int focused) { };
virtual ARGB32 getTextColor(LPARAM lParam);
int getTextAntialias(LPARAM lParam) { return antialias; }
virtual int getTextBold(LPARAM lParam) { return 0; }
virtual int getTextItalic(LPARAM lParam) { return 0; }
virtual ARGB32 getSelBgColor(LPARAM lParam);
virtual ARGB32 getSelFgColor(LPARAM lParam);
virtual ARGB32 getBgColor();
virtual ARGB32 getFocusColor(LPARAM lParam);
virtual ARGB32 getFocusRectColor(LPARAM lParam);
virtual int needFocusRect(LPARAM lParam) { return 0; }
virtual ARGB32 getColumnSepColor();
virtual int wantColSepOnItems();
virtual int getXShift();
public:
int insertColumn(ListColumn *col, int pos=-1, int alignment=COL_LEFTALIGN);// -1 is add to end
// void deleteColumn(int pos);
void deleteAllColumns();
void setHoverSelect(int a) { hoverselect = a; }
int getHoverSelect() { return hoverselect; }
void setSelectOnUpDown(int i) { selectonupdown = i; }
int getSelectOnUpDown() { return selectonupdown; }
virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
/**
Method
Will only work with simple text lists, be forwarned!!!
@see
@ret
*/
int getItemHeight();
void setItemHeight(int height, bool forceInvalidate = true);
int getIconWidth();
void setIconWidth(int width);
int getIconHeight();
void setIconHeight(int height);
protected:
virtual int getColumnsHeight();
virtual int getColumnsWidth();
virtual int getContentsWidth();
virtual int getContentsHeight();
virtual void drawBackground(Canvas *canvas);
void drawColumnHeaders(Canvas *c);
void drawItems(Canvas *canvas);
void updateScrollX();
void updateScrollY();
int doJumpToNext(wchar_t c, bool fromTop);
int fullyVisible(int pos);
virtual int onBeginDrag(int iItem);
virtual int dragOver(int x, int y, ifc_window *sourceWnd);
virtual void onSelectAll(); // hit Control-A
virtual void onDelete(); // hit 'delete'
virtual void onItemDelete(LPARAM lparam) {}
virtual void onDoubleClick(int itemnum); // double-click on an item
// this is called with the selected item#
virtual void onLeftClick(int itemnum); // left-click
// the second time you click on an already-focused item
virtual void onSecondLeftClick(int itemnum);
// this is called once for the item under cursor on click
virtual int onRightClick(int itemnum); // right-click on item
virtual int onIconLeftClick(int itemnum, int x, int y); // Returns 1 if we should not invoke onLeftClick()
// override this to be notified of item selections & deselections
virtual void onItemSelection(int itemnum, int selected);
virtual int onColumnDblClick(int col, int x, int y) { return 0; }
virtual int onColumnLabelClick(int col, int x, int y);
void selectRect(int x1, int y1, int x2, int y2);
void drawRect(int x1, int y1, int x2, int y2);
// interface to Freelist
listItem *createListItem();
void deleteListItem(listItem *item);
ListColumn *enumListColumn(int pos);
int getColumnPosByName(const wchar_t *name);
int delColumnByPos(int pos);
public: // Martin> dunno why these were protected...
void setShowIcons(int icons);
int getShowIcons(); // Maybe useful or not
SkinBitmap *getItemIcon(int item);
void setItemIcon(int pos, const wchar_t *bitmapid);
protected:
int item_invalidate_border;
bool showColumnsHeaders;
void recalcHeaders();
void itemSelection(int itemnum, int selected);
private:
int doAddItem(const wchar_t *label, LPARAM lParam, int pos);
int hitTestColumns(POINT p, int *origin=NULL);
int hitTestColumnClient(int x);
int hitTestColumnsLabel(POINT p);
void drawXorLine(int x);
void calcNewColWidth(int col, int x);
void calcBounds();
void onDragTimer();
void notifySelChanged(int item=-1, int sel=-1);
virtual int wantResizeCols() { return 1; }
int autosort, ownerdraw;
int textsize;
int itemHeight;
int iconWidth; // If it's still negative use itemHeight instead -- better user getIconWidth()
int iconHeight;
bool metrics_ok;
bool redraw;
int columnsHeight;
int dragtimeron;
int antialias;
PtrList<ListColumn> columnsList;
PtrListQuickSorted<listItem,CompareListItem> itemList;
int firstItemVisible;
int lastItemVisible;
listItem *lastItemFocused;
int lastItemFocusedPos;
listItem *lastAddedItem;
SelItemList selItemList;
int dragskip;
int dragskipcount;
int selectionStart;
int colresize;
POINT colresizept;
bool resizing_col;
int colresizeo;
bool processbup;
bool bdown;
bool nodrag;
int bdownx, bdowny;
bool firstComplete, lastComplete;
int rectselecting;
POINT selectStart;
POINT selectLast;
int sortdir, sortcol, lastcolsort;
int preventMultipleSelection;
Freelist<listItem> listItem_freelist;
int wantautodeselect;
int hoverselect;
int selectonupdown;
PtrList<ifc_window> tempselectnotifies;
StringW accessibleItemName;
int showicons;
private:
/* XML Parameters */
static XMLParamPair params[];
int xuihandle;
bool hasUserBg;
enum
{
LIST_ANTIALIAS = 0,
LIST_BACKGROUND,
LIST_TILE,
LIST_NOCOLHEADER,
};
protected:
int setXuiParam(int xuihandle, int xmlattributeid, const wchar_t *xmlattributename, const wchar_t *value);
};
#endif
+32
View File
@@ -0,0 +1,32 @@
#include <precomp.h>
#include "oswnd.h"
int OSWnd::onInit()
{
OSWND_PARENT::onInit();
onSetVisible(isVisible());
return 1;
}
void OSWnd::onSetVisible(int show)
{
#ifdef WIN32
ShowWindow(getOSHandle(), show ? SW_NORMAL : SW_HIDE);
#endif
}
int OSWnd::onResize()
{
OSWND_PARENT::onResize();
#ifdef WIN32
if (getOSHandle())
{
RECT r;
getClientRect(&r);
SetWindowPos(getOSHandle(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE);
}
#endif
return 1;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef __OSWND_H
#define __OSWND_H
#include <api/wnd/wndclass/guiobjwnd.h>
#define OSWND_PARENT GuiObjectWnd
class OSWnd : public OSWND_PARENT
{
public:
virtual int onInit();
virtual void onSetVisible(int show);
virtual int onResize();
virtual int handleRatio() { return 0; }
virtual HWND getOSHandle() = 0;
};
#endif
+14
View File
@@ -0,0 +1,14 @@
#include <precomp.h>
#include "oswndhost.h"
#ifdef CBCLASS
#undef CBCLASS
#endif
#define CBCLASS OSWndHostI
START_DISPATCH;
VCB(OSWNDHOST_OSWNDHOST_HOST, oswndhost_host);
VCB(OSWNDHOST_OSWNDHOST_UNHOST, oswndhost_unhost);
VCB(OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS, oswndhost_setRegionOffsets);
END_DISPATCH;
+53
View File
@@ -0,0 +1,53 @@
#ifndef __OSWNDHOST_H
#define __OSWNDHOST_H
#include <bfc/dispatch.h>
// {7050AACF-2731-4319-AF32-4ECE4CC8BDC4}
static const GUID osWndHostGuid =
{ 0x7050aacf, 0x2731, 0x4319, { 0xaf, 0x32, 0x4e, 0xce, 0x4c, 0xc8, 0xbd, 0xc4 } };
class OSWndHost : public Dispatchable
{
public:
void oswndhost_host(HWND oswnd);
void oswndhost_unhost();
void oswndhost_setRegionOffsets(RECT *r);
DISPATCH_CODES
{
OSWNDHOST_OSWNDHOST_HOST = 0,
OSWNDHOST_OSWNDHOST_UNHOST = 5,
OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS = 10,
};
};
inline void OSWndHost::oswndhost_host(HWND oswnd)
{
_voidcall(OSWNDHOST_OSWNDHOST_HOST, oswnd);
}
inline void OSWndHost::oswndhost_unhost()
{
_voidcall(OSWNDHOST_OSWNDHOST_UNHOST);
}
inline void OSWndHost::oswndhost_setRegionOffsets(RECT *r)
{
_voidcall(OSWNDHOST_OSWNDHOST_SETREGIONOFFSETS, r);
}
class OSWndHostI : public OSWndHost
{
public:
virtual void oswndhost_host(HWND oswnd) = 0;
virtual void oswndhost_unhost() = 0;
virtual void oswndhost_setRegionOffsets(RECT *r) = 0;
protected:
RECVS_DISPATCH;
};
#endif
+357
View File
@@ -0,0 +1,357 @@
#include <precomp.h>
#include "qpaintwnd.h"
#include <tataki/canvas/bltcanvas.h>
#include "../nu/threadpool/TimerHandle.hpp"
#define TIMER_QUICKPAINT 0x650
// thread context, this is here so we can avoid the windows types in quickpaintwnd.h
class QuickPaintContext
{
public:
QuickPaintContext(QuickPaintWnd *_wnd, int timeout)
{
killswitch = 0;
wnd = _wnd;
death = CreateEvent(NULL, FALSE, FALSE, NULL);
timer_ms = timeout;
WASABI_API_THREADPOOL->AddHandle(0, timer_handle, QPThreadPoolFunc, (void *)this, 0, 0/*api_threadpool::FLAG_LONG_EXECUTION*/);
timer_handle.Wait(timer_ms);
}
~QuickPaintContext()
{
CloseHandle(death);
timer_handle.Close();
}
void Kill()
{
InterlockedExchangePointer((volatile PVOID*)&wnd, 0);
killswitch=1;
WaitForSingleObject(death, INFINITE);
}
QuickPaintWnd *wnd;
TimerHandle timer_handle;
HANDLE death;
volatile int killswitch;
int timer_ms;
static int QPThreadPoolFunc(HANDLE h, void *user_data, intptr_t t);
};
int QuickPaintContext::QPThreadPoolFunc(HANDLE h, void *user_data, intptr_t t)
{
QuickPaintContext *context = (QuickPaintContext *)user_data;
if (context->killswitch)
{
WASABI_API_THREADPOOL->RemoveHandle(0, h);
SetEvent(context->death);
}
else
{
DWORD start = GetTickCount();
QuickPaintWnd *wnd = 0;
InterlockedExchangePointer((volatile PVOID*)&wnd, context->wnd);
if (wnd)
{
wnd->quickPaint();
TimerHandle timer_handle(h);
DWORD end = GetTickCount();
if (end-start > (DWORD)context->timer_ms)
timer_handle.Wait(1);
else
timer_handle.Wait(context->timer_ms - (end - start));
}
}
return 0;
}
// -----------------------------------------------------------------------
QuickPaintWnd::QuickPaintWnd()
{
invalidates_required = 0;
realtime = 1;
canvas_w = -1;
canvas_h = -1;
timerset = 0;
speed = 25;
enabled = 0;
render_canvas1 = NULL;
render_canvas2 = NULL;
paint_canvas = NULL;
thread_context = 0;
while (1)
{
svc_skinFilter *obj = sfe.getNext();
if (!obj) break;
filters.addItem(obj);
}
invalidated = 0;
}
// -----------------------------------------------------------------------
QuickPaintWnd::~QuickPaintWnd()
{
foreach(filters)
sfe.release(filters.getfor());
endfor;
KillThread();
delete render_canvas1;
delete render_canvas2;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::setRealtime(int rt)
{
realtime = rt;
}
// -----------------------------------------------------------------------
int QuickPaintWnd::getRealtime() const
{
return realtime;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::setSpeed(int ms)
{
speed = ms;
if (enabled && timerset)
{
if (thread_context)
thread_context->timer_ms = ms;
// let it change the timer value on the invalidate() timer
killTimer(TIMER_QUICKPAINT);
setTimer(TIMER_QUICKPAINT, getSpeed());
}
}
// -----------------------------------------------------------------------
void QuickPaintWnd::startQuickPaint()
{
enabled = 1;
if (!isInited()) return;
CreateRenderThread();
timerset=1;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::stopQuickPaint()
{
enabled = 0;
if (!isInited()) return;
KillThread();
timerset=0;
}
// -----------------------------------------------------------------------
int QuickPaintWnd::isQuickPainting()
{
return enabled;
}
// -----------------------------------------------------------------------
int QuickPaintWnd::getSpeed()
{
return speed;
}
// -----------------------------------------------------------------------
int QuickPaintWnd::onInit()
{
QUICKPAINTWND_PARENT::onInit();
if (enabled)
{
ASSERT(!thread_context);
CreateRenderThread();
timerset = 1;
}
return 1;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::timerCallback(int id)
{
switch (id)
{
case TIMER_QUICKPAINT:
if (invalidates_required)
{
invalidated = 1;
if (getRealtime() && isVisible() && !isMinimized())
cascadeRepaint();
else
invalidate();
InterlockedExchange(&invalidates_required, 0);
}
//quickPaint();
break;
default:
QUICKPAINTWND_PARENT::timerCallback(id);
}
}
void QuickPaintWnd::SetPaintingCanvas(BltCanvas *c)
{
InterlockedExchangePointer((volatile PVOID*)&paint_canvas, c);
}
BltCanvas *&QuickPaintWnd::GetDrawingConvas()
{
if (paint_canvas == render_canvas2)
return render_canvas1;
else
return render_canvas2;
}
// -----------------------------------------------------------------------
int QuickPaintWnd::quickPaint()
{
int repaint=0;
int w, h;
getQuickPaintSize(&w, &h);
if (wantEvenAlignment())
{
if (w & 1) w++;
if (h & 1) h++;
}
if (w == 0 && h == 0) return 0;
BltCanvas *&render_canvas = GetDrawingConvas();
int newone = 0;
if (canvas_w != w || canvas_h != h)
{
delete render_canvas1; render_canvas1=0;
delete render_canvas2; render_canvas2=0;
}
if (!render_canvas)
{
render_canvas = new BltCanvas(w, wantNegativeHeight() ? -h : h, getOsWindowHandle());
canvas_w = w;
canvas_h = h;
newone = 1;
}
repaint = onQuickPaint(render_canvas, canvas_w, canvas_h, newone);
SetPaintingCanvas(render_canvas);
if (repaint)
InterlockedIncrement(&invalidates_required);
return repaint;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::getQuickPaintSize(int *w, int *h)
{
RECT r;
getClientRect(&r);
if (w) *w = r.right - r.left;
if (h) *h = r.bottom - r.top;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::getQuickPaintSource(RECT *r)
{
ASSERT(r != NULL);
r->left = 0;
r->right = canvas_w;
r->top = 0;
r->bottom = canvas_h;
}
// -----------------------------------------------------------------------
void QuickPaintWnd::getQuickPaintDest(RECT *r)
{
ASSERT(r != NULL);
getClientRect(r);
}
// -----------------------------------------------------------------------
void QuickPaintWnd::onSetVisible(int show)
{
QUICKPAINTWND_PARENT::onSetVisible(show);
if (!show)
{
if (timerset)
{
KillThread();
timerset = 0;
}
}
else
{
if (enabled && !timerset)
{
CreateRenderThread();
timerset = 1;
}
}
}
// -----------------------------------------------------------------------
int QuickPaintWnd::onPaint(Canvas *canvas)
{
QUICKPAINTWND_PARENT::onPaint(canvas);
if (!enabled) return 1;
BltCanvas *render_canvas;
InterlockedExchangePointer((volatile PVOID*)&render_canvas, paint_canvas);
if (!render_canvas) return 1;
RECT r;
getQuickPaintDest(&r);
RECT sr;
getQuickPaintSource(&sr);
if (invalidated && wantFilters())
{
foreach(filters)
filters.getfor()->filterBitmap((unsigned char *)render_canvas->getBits(), canvas_w, canvas_h, 32, NULL, getFiltersGroup());
endfor;
invalidated = 0;
}
render_canvas->/*getSkinBitmap()->*/stretchToRectAlpha(canvas, &sr, &r, getPaintingAlpha());
InterlockedExchange(&invalidates_required, 0);
return 1;
}
void QuickPaintWnd::KillThread()
{
if (thread_context)
{
killTimer(TIMER_QUICKPAINT);
thread_context->Kill();
delete thread_context;
thread_context = 0;
}
}
void QuickPaintWnd::CreateRenderThread()
{
int sp = getSpeed();
if (!thread_context)
{
thread_context = new QuickPaintContext(this, sp);
}
else
thread_context->timer_ms = sp;
setTimer(TIMER_QUICKPAINT, sp);
}
+154
View File
@@ -0,0 +1,154 @@
#ifndef __QPAINTWND_H
#define __QPAINTWND_H
#include <api/wnd/wndclass/guiobjwnd.h>
#include <api/service/svcs/svc_skinfilter.h>
#define QUICKPAINTWND_PARENT GuiObjectWnd
/**
class QuickPaintWnd .
@short
@author Nullsoft
@ver 1.0
@see
@cat BFC
*/
class QuickPaintContext;
class QuickPaintWnd : public QUICKPAINTWND_PARENT {
public:
/**
QuickPaintWnd constructor .
@see ~QuickPaintWnd()
*/
QuickPaintWnd();
/**
Destructor for QuickPaintWnd .
@see QuickPaintWnd()
*/
virtual ~QuickPaintWnd();
/**
QuickPaintWnd method onInit .
@ret 1
*/
virtual int onInit();
virtual int onPaint(Canvas *c);
/**
QuickPaintWnd method timerCallback .
@param id Identifies requested action
*/
virtual void timerCallback(int id);
virtual void onSetVisible(int show);
/**
QuickPaintWnd method setRealtime .
@see getRealtime()
@param rt
*/
virtual void setRealtime(int rt);
int getRealtime() const;
/**
QuickPaintWnd method setSpeed sets the timer interval in milliseconds.
@see getSpeed()
@param ms The timer interval in milliseconds.
*/
virtual void setSpeed(int ms);
/**
QuickPaintWnd method getSpeed gets the timer interval in milliseconds.
@see setSpeed()
@param ms The timer interval in milliseconds.
*/
virtual int getSpeed();
/**
QuickPaintWnd method startQuickPaint .
*/
virtual void startQuickPaint();
/**
QuickPaintWnd method stopQuickPaint .
*/
virtual void stopQuickPaint();
/**
QuickPaintWnd method isQuickPainting .
*/
virtual int isQuickPainting();
virtual int onQuickPaint(BltCanvas *c, int w, int h, int newone) { return 0; } // return 1 if your content has changed, or 0 to cancel update of your buffer to the window
virtual int wantEvenAlignment() { return 0; } // if you need even coordinates for your framebuffer, return 1 here
/**
QuickPaintWnd method getQuickPaintSize gets the client area width and
height.
@param w A pointer to the width to fill.
@param h A pointer to the height to fill.
*/
virtual void getQuickPaintSize(int *w, int *h); // by default returns client width/height
/**
QuickPaintWnd method getQuickPaintSource .
@see getQuickPaintSize()
@assert r exists.
@ret None
@except
@param r
*/
virtual void getQuickPaintSource(RECT *r); // by default returns the size of the quickpaint canvas
/**
QuickPaintWnd method getQuickPaintDest .
@see getQuickPaintSource()
@assert r exists.
@param r
*/
virtual void getQuickPaintDest(RECT *r); // by default returns the size of client area
virtual int wantNegativeHeight() { return 0; }
virtual int wantFilters() { return 0; }
virtual const wchar_t *getFiltersGroup() { return L"Vis/Eq"; }
protected:
int invalidated;
private:
/**
QuickPaintWnd method quickPaint .
*/
friend class QuickPaintContext;
int quickPaint();
void KillThread();
void CreateRenderThread();
int realtime;
volatile LONG invalidates_required;
BltCanvas *render_canvas1, *render_canvas2, *paint_canvas;
void SetPaintingCanvas(BltCanvas *c);
BltCanvas *&GetDrawingConvas();
int canvas_w, canvas_h;
int speed;
int timerset;
int enabled;
PtrList<svc_skinFilter>filters;
SkinFilterEnum sfe;
QuickPaintContext *thread_context;
};
#endif
@@ -0,0 +1,113 @@
#include "precomp.h"
#include <api/wnd/api_wnd.h>
#include "rootwndholder.h"
#include <api/wnd/notifmsg.h>
#include <tataki/canvas/canvas.h>
RootWndHolder::RootWndHolder() {
privptr = NULL;
}
RootWndHolder::~RootWndHolder() {
}
void RootWndHolder::rootwndholder_getRect(RECT *r) {
if (isInited())
getClientRect(r);
else
MEMSET(r, 0, sizeof(RECT));
}
int RootWndHolder::onInit() {
ROOTWNDHOLDER_PARENT::onInit();
ifc_window *w = rootwndholder_getRootWnd();
if (w) {
checkInit(w);
setName(rootwndholder_getRootWnd()->getRootWndName());
}
return 1;
}
void RootWndHolder::checkInit(ifc_window *w) {
if (w && !w->isInited()) {
if (w->getParent() == NULL)
w->setParent(this);
// w->setStartHidden(getStartHidden());
w->init(this);
}
}
int RootWndHolder::onResize() {
int rv = ROOTWNDHOLDER_PARENT::onResize();
if (!isInited()) return 1;
ifc_window *held = rootwndholder_getRootWnd();
if (!held) return rv;
RECT r;
rootwndholder_getRect(&r);
if (renderRatioActive() && !held->handleRatio())
multRatio(&r);
held->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
return rv;
}
/*void RootWndHolder::onSetVisible(int v) {
ROOTWNDHOLDER_PARENT::onSetVisible(v);
if (!rootwndholder_getRootWnd()) return;
rootwndholder_getRootWnd()->setVisible(v);
}*/
int RootWndHolder::onActivate() {
int r = ROOTWNDHOLDER_PARENT::onActivate();
if (rootwndholder_getRootWnd())
rootwndholder_getRootWnd()->onActivate();
return r;
}
int RootWndHolder::onDeactivate() {
int r = ROOTWNDHOLDER_PARENT::onDeactivate();
if (rootwndholder_getRootWnd())
rootwndholder_getRootWnd()->onDeactivate();
return r;
}
int RootWndHolder::getPreferences(int what) {
if (rootwndholder_getRootWnd())
return rootwndholder_getRootWnd()->getPreferences(what);
return ROOTWNDHOLDER_PARENT::getPreferences(what);
}
ifc_window *RootWndHolder::rootwndholder_getRootWnd() {
return privptr;
}
void RootWndHolder::rootwndholder_setRootWnd(ifc_window *w) {
if (privptr == w) return;
privptr = w;
checkInit(w);
if (isPostOnInit())
onResize();
}
int RootWndHolder::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
if (rootwndholder_getRootWnd())
return rootwndholder_getRootWnd()->onAction(action, param, x, y, p1, p2, data, datalen, source);
return ROOTWNDHOLDER_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
}
int RootWndHolder::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
if (msg == ChildNotify::NAMECHANGED && child == rootwndholder_getRootWnd())
setName(child->getRootWndName());
return passNotifyUp(child, msg, (int)param1, (int)param2);
}
int RootWndHolder::onPaint(Canvas *c) {
int rt = ROOTWNDHOLDER_PARENT::onPaint(c);
if (wantRenderBaseTexture()) {
RECT r;
rootwndholder_getRect(&r);
WASABI_API_WND->skin_renderBaseTexture(getBaseTextureWindow(), c, r, this);
}
return rt;
}
@@ -0,0 +1,41 @@
#ifndef __ROOTWNDHOLD_H
#define __ROOTWNDHOLD_H
#include <api/wnd/virtualwnd.h>
/**
A simple wnd that holds another window. Initializes it if needed, but DOES not delete it (and for a good reason, this is a ifc_window),
so your inheritor has to call whoever is needed to destroy the wnd
*/
#define ROOTWNDHOLDER_PARENT VirtualWnd
class RootWndHolder : public ROOTWNDHOLDER_PARENT
{
public:
RootWndHolder();
virtual ~RootWndHolder();
// override this
virtual ifc_window *rootwndholder_getRootWnd();
virtual void rootwndholder_getRect(RECT *r);
virtual void rootwndholder_setRootWnd(ifc_window *w);
// BaseWnd
virtual int onInit();
virtual int onResize();
// virtual void onSetVisible(int v);
virtual int wantRenderBaseTexture() { return 0; }
virtual int onPaint(Canvas *c);
virtual int onActivate();
virtual int onDeactivate();
virtual int getPreferences(int what);
virtual int onAction(const wchar_t *action, const wchar_t *param=NULL, int x=-1, int y=-1, intptr_t p1=0, intptr_t p2=0, void *data=NULL, size_t datalen=0, ifc_window *source=NULL);
virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
private:
void checkInit(ifc_window *w);
ifc_window *privptr;
};
#endif
+869
View File
@@ -0,0 +1,869 @@
#include <precomp.h>
#include "scbkgwnd.h"
#include <api/wnd/notifmsg.h>
#include <bfc/wasabi_std_wnd.h>
#include <api/wnd/PaintCanvas.h>
#define SCROLLBAR_SEP 4
#define TIMER_SMOOTHSCROLLY 8873
#define TIMER_SMOOTHSCROLLX 8874
#define SMOOTH_STEPS 5
#define DEFAULT_BGCOLOR RGB(0,0,0)
ScrlBkgWnd::ScrlBkgWnd()
{
inDestroy = FALSE;
bmp = NULL;
bgColor = DEFAULT_BGCOLOR;
scrollX = 0;
scrollY = 0;
dbbuffer = 1;
needSetSliders = FALSE;
lineHeight = 16;
wantsep = 0;
wantTileBg = true;
lastratio = 1.0;
MEMSET(&smsqr, 0, sizeof(RECT));
in_set_slider_position = 0;
smoothScrollYInc = smoothScrollXInc = 0;
smoothScrollYCur = smoothScrollXCur = 0;
smoothScrollYTimerCount = smoothScrollXTimerCount = 0;
smoothYTimer = smoothXTimer = 0;
}
ScrlBkgWnd::~ScrlBkgWnd()
{
inDestroy = TRUE;
}
int ScrlBkgWnd::onInit()
{
SCRLBKGWND_PARENT::onInit();
scrollY = 0;
scrollX = 0;
hSep.setOrientation(SEP_HORIZONTAL);
hScroll.setBitmaps(L"wasabi.scrollbar.horizontal.left",
L"wasabi.scrollbar.horizontal.left.pressed",
L"wasabi.scrollbar.horizontal.left.hover",
L"wasabi.scrollbar.horizontal.right",
L"wasabi.scrollbar.horizontal.right.pressed",
L"wasabi.scrollbar.horizontal.right.hover",
L"wasabi.scrollbar.horizontal.button",
L"wasabi.scrollbar.horizontal.button.pressed",
L"wasabi.scrollbar.horizontal.button.hover");
hScroll.setBackgroundBitmaps(L"wasabi.scrollbar.horizontal.background.left",
L"wasabi.scrollbar.horizontal.background.middle",
L"wasabi.scrollbar.horizontal.background.right");
vSep.setOrientation(SEP_VERTICAL);
vScroll.setBitmaps(L"wasabi.scrollbar.vertical.left",
L"wasabi.scrollbar.vertical.left.pressed",
L"wasabi.scrollbar.vertical.left.hover",
L"wasabi.scrollbar.vertical.right",
L"wasabi.scrollbar.vertical.right.pressed",
L"wasabi.scrollbar.vertical.right.hover",
L"wasabi.scrollbar.vertical.button",
L"wasabi.scrollbar.vertical.button.pressed",
L"wasabi.scrollbar.vertical.button.hover");
vScroll.setBackgroundBitmaps(L"wasabi.scrollbar.vertical.background.top",
L"wasabi.scrollbar.vertical.background.middle",
L"wasabi.scrollbar.vertical.background.bottom");
// hScroll->setVertical(FALSE);
vScroll.setVertical(TRUE);
hScroll.setStartHidden(TRUE); // prevent showing window at creation
vScroll.setStartHidden(TRUE);
hSep.setStartHidden(TRUE);
vSep.setStartHidden(TRUE);
hScroll.setParent(this);
vScroll.setParent(this);
hSep.setParent(this);
vSep.setParent(this);
hScroll.init(getOsModuleHandle(), getOsWindowHandle());
vScroll.init(getOsModuleHandle(), getOsWindowHandle());
hSep.init(getOsModuleHandle(), getOsWindowHandle());
vSep.init(getOsModuleHandle(), getOsWindowHandle());
hScroll.setPosition(0);
vScroll.setPosition(0);
setSlidersPosition(); // position sliders and show them if needed
return 1;
}
void ScrlBkgWnd::setBgBitmap(const wchar_t *b)
{
bmp = b;
if (b) setBgColor(DEFAULT_BGCOLOR);
}
void ScrlBkgWnd::setBgColor(ARGB32 rgb)
{
bgColor = rgb;
}
SkinBitmap *ScrlBkgWnd::getBgBitmap(void)
{
return bmp;
}
ARGB32 ScrlBkgWnd::getBgColor(void)
{
return bgColor;
}
// Scroll to a specified Y-pixels
void ScrlBkgWnd::scrollToY(int y, int signal)
{
WndCanvas *canvas = NULL;
RECT r;
int offset;
int dor2 = 0;
RECT r2 = {0, 0, 0, 0};
int focused = gotFocus();
if (isVirtual() || renderRatioActive())
{
scrollY = y;
invalidateRect(&clientRect());
onScrollY(y);
return ;
}
if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ; // no need to paint
if (y > scrollY)
{ // tree scrolling up, scroller going down. invalidating from the bottom. bitblting from bottom to top
int lines = y - scrollY;
offset = -lines;
getClientRect(&r);
canvas = new WndCanvas();
canvas->attachToClient(this);
RegionI reg;
makeWindowOverlayMask(&reg);
RegionI clip(&r);
reg.offset(0, offset);
clip.subtractRegion(&reg);
canvas->selectClipRgn(&clip);
int b = hScroll.isVisible() ? hScroll.getHeight() : 0;
int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
int a = focused && (!b);
if (r.bottom-r.top-lines > 0)
canvas->blit(r.left, r.top+lines, canvas, r.left, r.top, r.right-r.left- c, r.bottom-r.top-lines-a - b);
// int a = focused && (!hScroll->isVisible());
//if (r.bottom - r.top - lines > 0)
// canvas->blit(r.left, r.top + lines, canvas, r.left, r.top, r.right - r.left, r.bottom - r.top - lines - a);
canvas->selectClipRgn(NULL);
if (!clip.isEmpty())
invalidateRgn(&clip);
getClientRect(&r2);
r2.bottom = r2.top + 1;
dor2 = 1;
r.top = r.bottom - lines - 1;
}
if (y < scrollY)
{ // tree scrolling down, scroller going up. invalidating from the top. bitblting from top to bottom
int lines = scrollY - y;
offset = lines;
getClientRect(&r);
canvas = new WndCanvas();
canvas->attachToClient(this);
RegionI reg;
makeWindowOverlayMask(&reg);
RegionI clip(&r);
reg.offset(0, offset);
clip.subtractRegion(&reg);
canvas->selectClipRgn(&clip);
int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
canvas->blit(r.left, r.top+focused, canvas, r.left, r.top+lines+focused, r.right-r.left-c, r.bottom-r.top-lines-focused);
//canvas->blit(r.left, r.top + focused, canvas, r.left, r.top + lines + focused, r.right - r.left, r.bottom - r.top - lines - focused);
canvas->selectClipRgn(NULL);
if (!clip.isEmpty())
invalidateRgn(&clip);
getClientRect(&r2);
r2.top = r2.bottom - 1;
dor2 = 1;
r.bottom = r.top + lines + 1;
}
if (canvas)
{
delete canvas;
scrollY = y;
// in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
RECT cr;
getClientRect(&cr);
cr.top -= getHeaderHeight();
RECT screenblit;
SubtractRect(&screenblit, &cr, &r);
// invalidate what's needed
if (dor2 && focused)
cascadeRepaintRect(&r2, 0);
cascadeRepaintRect(&r);
deferedInvalidateRect(&screenblit);
//dbbuffer = 1;
//repaint();
}
if (signal)
updateVScroll(y);
onScrollY(y);
}
// Scroll to a specified X-pixel
void ScrlBkgWnd::scrollToX(int x, int signal)
{
WndCanvas *canvas = NULL;
RECT r;
int offset;
int dor2 = 0;
RECT r2 = {0, 0, 0, 0};
int focused = gotFocus();
if (isVirtual() || ABS(getRenderRatio() - 1.0) > 0.01)
{
scrollX = x;
getClientRect(&r);
invalidateRect(&r);
return ;
}
if (x > scrollX)
{ // tree scrolling left, scroller going right. invalidating from the right. bitblting from right to left
int lines = x - scrollX;
offset = -lines;
getClientRect(&r);
r.top -= getHeaderHeight();
canvas = new WndCanvas();
canvas->attachToClient(this);
RegionI reg;
makeWindowOverlayMask(&reg);
RegionI clip(&r);
reg.offset(offset, 0);
clip.subtractRegion(&reg);
canvas->selectClipRgn(&clip);
int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
canvas->blit(r.left+lines, r.top, canvas, r.left, r.top, r.right-r.left-lines-focused-c, r.bottom-r.top);
//canvas->blit(r.left + lines, r.top, canvas, r.left, r.top, r.right - r.left - lines - focused, r.bottom - r.top);
canvas->selectClipRgn(NULL);
if (!reg.isEmpty())
invalidateRgn(&reg);
getClientRect(&r2);
r2.right = r2.left + 1;
dor2 = 1;
r.left = r.right - lines - 1;
}
if (x < scrollX)
{ // tree scrolling right, scroller going left. invalidating from the left. bitblting from left to right
int lines = scrollX - x;
offset = lines;
getClientRect(&r);
r.top -= getHeaderHeight();
canvas = new WndCanvas();
canvas->attachToClient(this);
RegionI reg;
makeWindowOverlayMask(&reg);
RegionI clip(&r);
reg.offset(offset, 0);
clip.subtractRegion(&reg);
canvas->selectClipRgn(&clip);
int a = focused && (!vScroll.isVisible());
int c = hScroll.isVisible() ? hScroll.getHeight()-focused : 0;
canvas->blit(r.left+a, r.top, canvas, r.left+lines, r.top, r.right-r.left-lines-a, r.bottom-r.top-c);
//int a = focused && (!vScroll->isVisible());
// canvas->blit(r.left + a, r.top, canvas, r.left + lines, r.top, r.right - r.left - lines - a, r.bottom - r.top);
canvas->selectClipRgn(NULL);
if (!reg.isEmpty())
invalidateRgn(&reg);
getClientRect(&r2);
r2.left = r2.right - 1;
dor2 = 1;
r.right = r.left + lines + 1;
}
if (canvas)
{
delete canvas;
scrollX = x;
// in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
RECT cr;
getClientRect(&cr);
cr.top -= getHeaderHeight();
RECT screenblit;
SubtractRect(&screenblit, &cr, &r);
deferedInvalidateRect(&screenblit);
if (dor2 && focused)
cascadeRepaintRect(&r2, 0);
// invalidate what's needed
cascadeRepaintRect(&r);
//dbbuffer = 1;
//repaint();
}
if (signal)
updateHScroll(x);
}
void ScrlBkgWnd::setSlidersPosition()
{
if (in_set_slider_position) return ;
in_set_slider_position = 1;
_setSlidersPosition();
in_set_slider_position = 0;
}
void ScrlBkgWnd::_setSlidersPosition()
{
if (!isInited()) return ;
RECT d;
getClientRect(&d);
if ((d.left >= d.right) || (d.top >= d.bottom))
return ;
RECT r;
if (inDestroy) return ;
if (!isVisible())
{
needSetSliders = TRUE;
return ;
}
needSetSliders = FALSE;
if (needHScroll())
{
SCRLBKGWND_PARENT::getClientRect(&r);
r.top = r.bottom - getScrollbarWidth();
if (needVScroll())
r.right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
RECT z; hScroll.getClientRect(&z);
if (!Wasabi::Std::rectEqual(r, z))
{ // assumes ScrollBars are virtual
hScroll.resizeToRect(&r);
RECT s = r;
s.bottom = s.top;
s.top -= (wantsep ? SCROLLBAR_SEP : 0);
hSep.resizeToRect(&s);
}
if (!hScroll.isVisible())
{
hScroll.setVisible(TRUE);
if (wantsep) hSep.setVisible(TRUE);
onHScrollToggle(1);
}
hScroll.setNPages(((int)(getContentsWidth() / (r.right - r.left))) + 1);
hScroll.setUpDownValue((int)(((float)lineHeight / (getContentsWidth() - (r.right - r.left)))*SCROLLBAR_FULL));
hScroll.setPosition((int)((float)scrollX / getMaxScrollX() * SCROLLBAR_FULL));
}
else
{
if (hScroll.isVisible())
{
hScroll.setVisible(FALSE);
if (wantsep) hSep.setVisible(FALSE);
onHScrollToggle(0);
}
hScroll.setPosition(0);
scrollToX(0);
}
if (needVScroll())
{
SCRLBKGWND_PARENT::getClientRect(&r);
r.left = r.right - getScrollbarWidth();
if (needHScroll())
r.bottom -= getScrollbarWidth();
RECT z; vScroll.getNonClientRect(&z);
if (!Wasabi::Std::rectEqual(r, z))
{
vScroll.resizeToRect(&r);
RECT s = r;
s.right = s.left;
s.left -= (wantsep ? SCROLLBAR_SEP : 0);
vSep.resizeToRect(&s);
}
if (!vScroll.isVisible())
{
vScroll.setVisible(TRUE);
if (wantsep) vSep.setVisible(TRUE);
onVScrollToggle(1);
}
vScroll.setNPages(((int)(getContentsHeight() / (r.bottom - r.top))) + 1);
vScroll.setUpDownValue((int)(((float)lineHeight / (getContentsHeight() - (r.bottom - r.top)))*SCROLLBAR_FULL));
vScroll.setPosition((int)((float)scrollY / getMaxScrollY() * SCROLLBAR_FULL));
}
else
{
if (vScroll.isVisible())
{
vScroll.setVisible(FALSE);
if (wantsep) vSep.setVisible(FALSE);
onVScrollToggle(0);
}
vScroll.setPosition(0);
scrollToY(0);
}
hSep.invalidate();
vSep.invalidate();
if (needHScroll() && needVScroll())
{
getNonClientRect(&smsqr);
smsqr.left = smsqr.right - getScrollbarWidth();
smsqr.top = smsqr.bottom - getScrollbarWidth();
invalidateRect(&smsqr);
}
else
ZERO(smsqr);
}
void ScrlBkgWnd::onHScrollToggle(int set)
{}
void ScrlBkgWnd::onVScrollToggle(int set)
{}
int ScrlBkgWnd::onPaint(Canvas *canvas)
{
RECT d;
getClientRect(&d);
if (d.right > d.left + 0xFFFF || d.bottom > d.top + 0xFFFF) return 1;
if ((d.left >= d.right) || (d.top >= d.bottom))
{
return SCRLBKGWND_PARENT::onPaint(canvas);
}
if (needSetSliders) setSlidersPosition();
// RECT z;
// GetUpdateRect(gethWnd(), &z, FALSE);
PaintCanvas paintcanvas;
PaintBltCanvas paintbcanvas;
if (canvas == NULL)
{
if (dbbuffer)
{
if (!paintbcanvas.beginPaintNC(this)) return 0;
canvas = &paintbcanvas;
}
else
{
if (!paintcanvas.beginPaint(this)) return 0;
canvas = &paintcanvas;
}
}
//dbbuffer=1;
SCRLBKGWND_PARENT::onPaint(canvas);
RegionI *smsq = NULL;
if (needHScroll() && needVScroll())
{
renderBaseTexture(canvas, smsqr);
smsq = new RegionI(&smsqr);
}
RECT r;
LabelWnd::getNonClientRect(&r);
RECT c = {r.left, r.top, r.right, r.top + getLabelHeight()}; // create label rect
RegionI *clip = new RegionI();
if (canvas->getClipRgn(clip) == 0)
{
delete clip;
clip = new RegionI(&r);
if (smsq) clip->subtractRegion(smsq);
canvas->selectClipRgn(clip);
}
else
{
RegionI reg(&c);
clip->subtractRegion(&reg);
if (smsq) clip->subtractRegion(smsq);
canvas->selectClipRgn(clip);
}
delete smsq;
drawBackground(canvas);
delete clip;
if (getRenderRatio() != lastratio) { invalidate(); lastratio = getRenderRatio(); } // todo: make that an event
return 1;
}
int ScrlBkgWnd::needDoubleBuffer()
{
return dbbuffer;
}
int ScrlBkgWnd::onEraseBkgnd(HDC dc)
{
/* DCCanvas canvas;
canvas.cloneDC(dc);
drawBackground(&canvas);*/
return 1;
}
// Draws tiled background
void ScrlBkgWnd::drawBackground(Canvas *canvas)
{
RECT r(clientRect());
RegionI reg(&r);
RegionI old;
canvas->getClipRgn(&old);
reg.andRegion(&old);
canvas->selectClipRgn(&reg);
if (bmp.getBitmap() && bgColor == DEFAULT_BGCOLOR)
{
r.top -= scrollY % bmp.getBitmap()->getHeight();
r.left -= scrollX % bmp.getBitmap()->getWidth();
if (wantTileBg)
bmp.getBitmap()->blitTile(canvas, &r);
else
bmp.getBitmap()->stretchToRect(canvas, &r);
}
else if (bgColor != DEFAULT_BGCOLOR)
{
canvas->fillRect(&r, bgColor);
}
canvas->selectClipRgn(&old);
}
bool ScrlBkgWnd::needHScroll()
{
if (!wantHScroll()) return FALSE;
RECT r;
getNonClientRect(&r);
if (vScroll.isVisible())
r.right -= getScrollbarWidth();
return (getContentsWidth() > r.right - r.left);
}
bool ScrlBkgWnd::needVScroll()
{
if (!wantVScroll()) return FALSE;
RECT r;
getNonClientRect(&r);
r.top += getHeaderHeight();
if (hScroll.isVisible())
r.bottom -= getScrollbarWidth();
return (getContentsHeight() > r.bottom - r.top);
}
// Returns the current tree width in pixels
int ScrlBkgWnd::getContentsWidth()
{
/*RECT r;
ScrlBkgWnd::getClientRect(&r);
return r.right-r.left;*/
return 10000;
}
// Returns the current tree height in pixels
int ScrlBkgWnd::getContentsHeight()
{
/*RECT r;
ScrlBkgWnd::getClientRect(&r);
return r.bottom-r.top;*/
return 10000;
}
int ScrlBkgWnd::getMaxScrollY()
{
RECT r;
getClientRect(&r);
return MAX<int>(0, getContentsHeight() - (r.bottom - r.top));
}
int ScrlBkgWnd::getMaxScrollX()
{
RECT r;
getClientRect(&r);
return MAX<int>(0, getContentsWidth() - (r.right - r.left));
}
void ScrlBkgWnd::updateVScroll(int y)
{
if (getMaxScrollY() == 0) { vScroll.setPosition(0); return ; }
int z = (int)((float)y / getMaxScrollY() * SCROLLBAR_FULL);
vScroll.setPosition(z);
}
void ScrlBkgWnd::updateHScroll(int x)
{
if (getMaxScrollX() == 0) { hScroll.setPosition(0); return ; }
int z = (int)((float)x / getMaxScrollX() * SCROLLBAR_FULL);
hScroll.setPosition(z);
}
void ScrlBkgWnd::updateScrollY(bool smooth)
{
if (getMaxScrollY() == 0) { scrollToY(0); return ; }
int y = (int)((float)(vScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollY());
if (!smooth)
scrollToY(y /*& ~3*/);
else
smoothScrollToY(y);
}
void ScrlBkgWnd::updateScrollX(bool smooth)
{
if (getMaxScrollX() == 0) { scrollToX(0); return ; }
int x = (int)((float)(hScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollX());
if (!smooth)
scrollToX(x /*& ~3*/);
else
smoothScrollToX(x);
}
void ScrlBkgWnd::smoothScrollToX(int x)
{
killSmoothXTimer();
smoothScrollXInc = -(float)(scrollX - x) / SMOOTH_STEPS;
smoothScrollXCur = (float)scrollX;
smoothScrollXTimerCount = 0;
smoothXTimer = 1;
setTimer(TIMER_SMOOTHSCROLLX, 25);
}
void ScrlBkgWnd::killSmoothYTimer()
{
if (smoothYTimer)
{
killTimer(TIMER_SMOOTHSCROLLY);
smoothScrollYCur += smoothScrollYInc * (SMOOTH_STEPS - smoothScrollYTimerCount);
scrollToY((int)smoothScrollYCur);
smoothYTimer = 0;
updateVScroll(scrollY);
}
}
void ScrlBkgWnd::killSmoothXTimer()
{
if (smoothXTimer)
{
killTimer(TIMER_SMOOTHSCROLLX);
smoothScrollXCur += smoothScrollXInc * (SMOOTH_STEPS - smoothScrollXTimerCount);
scrollToX((int)smoothScrollXCur);
smoothXTimer = 0;
updateHScroll(scrollX);
}
}
void ScrlBkgWnd::smoothScrollToY(int y)
{
killSmoothYTimer();
smoothScrollYInc = -(float)(scrollY - y) / SMOOTH_STEPS;
smoothScrollYCur = (float)scrollY;
smoothScrollYTimerCount = 0;
smoothYTimer = 1;
setTimer(TIMER_SMOOTHSCROLLY, 25);
}
void ScrlBkgWnd::timerCallback(int id)
{
switch (id)
{
case TIMER_SMOOTHSCROLLY:
smoothScrollYCur += smoothScrollYInc;
scrollToY((int)smoothScrollYCur, FALSE);
if (++smoothScrollYTimerCount == SMOOTH_STEPS)
killSmoothYTimer();
return ;
case TIMER_SMOOTHSCROLLX:
smoothScrollXCur += smoothScrollXInc;
scrollToX((int)smoothScrollXCur, FALSE);
if (++smoothScrollXTimerCount == SMOOTH_STEPS)
killSmoothXTimer();
return ;
}
SCRLBKGWND_PARENT::timerCallback(id);
}
// Gets notification from sliders
int ScrlBkgWnd::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2)
{
switch (msg)
{
case ChildNotify::SCROLLBAR_SETPOSITION:
if (child == &vScroll)
{
updateScrollY(!!param1);
return 1;
}
if (child == &hScroll)
{
updateScrollX(!!param1);
return 1;
}
break;
}
return SCRLBKGWND_PARENT::childNotify(child, msg, param1, param2);
}
int ScrlBkgWnd::onResize()
{
int rt = SCRLBKGWND_PARENT::onResize();
if (!isInited()) return rt;
invalidateRect(&smsqr);
setSlidersPosition();
return 1;
}
void ScrlBkgWnd::onSetVisible(int show)
{
SCRLBKGWND_PARENT::onSetVisible(show);
if (show)
setSlidersPosition();
}
void ScrlBkgWnd::getClientRect(RECT *r)
{
SCRLBKGWND_PARENT::getClientRect(r);
if (vScroll.isVisible(1))
r->right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
if (hScroll.isVisible(1))
r->bottom -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
r->top += getHeaderHeight();
}
/*void ScrlBkgWnd::getNonClientRect(RECT *r) {
SCRLBKGWND_PARENT::getClientRect(r); // my non client rect is my parent's client rect
return;
}*/
int ScrlBkgWnd::getHeaderHeight()
{
return 0;
}
void ScrlBkgWnd::setLineHeight(int h)
{
lineHeight = h;
}
int ScrlBkgWnd::getLinesPerPage()
{
RECT r;
getClientRect(&r);
int h = r.bottom - r.top;
return h / lineHeight;
}
int ScrlBkgWnd::getScrollX()
{
return scrollX;
}
int ScrlBkgWnd::getScrollY()
{
return scrollY;
}
int ScrlBkgWnd::getScrollbarWidth()
{
// TODO: maybe do if (hScroll.isVisible())
return hScroll.getWidth();
return vScroll.getWidth();
return 0;
}
/*void ScrlBkgWnd::clientToScreen(RECT *r) {
POINT p;
p.x = r->left;
p.y = r->top;
SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
r->left = p.x;
r->top = p.y;
p.x = r->right;
p.y = r->bottom;
SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
r->right = p.x;
r->bottom = p.y;
}
void ScrlBkgWnd::clientToScreen(int *x, int *y) {
SCRLBKGWND_PARENT::clientToScreen(x, y);
}
void ScrlBkgWnd::clientToScreen(POINT *p) {
TREEWND_PARENT::clientToScreen((int *)&p->x, (int *)&p->y);
}*/
void ScrlBkgWnd::makeWindowOverlayMask(api_region *r)
{
return ;
#ifdef WIN32
// With this routine empty, I'm just nuking the code from x-plat builds < KP
HDC dc = GetDC(getOsWindowHandle());
//if (getRandomRgn)
{
RECT cr;
getClientRect(&cr);
RECT wr;
getWindowRect(&wr);
RegionI sr;
Wasabi::Std::Wnd::getRandomRegion(dc, sr.getOSHandle());
sr.offset( -wr.left, -wr.top);
r->setRect(&cr);
r->subtractRegion(&sr);
}
ReleaseDC(getOsWindowHandle(), dc);
#endif
}
+463
View File
@@ -0,0 +1,463 @@
#ifndef __SCRLBKGWND_H
#define __SCRLBKGWND_H
#include <tataki/canvas/canvas.h>
#include <tataki/bitmap/autobitmap.h>
#include <api/wnd/wndclass/labelwnd.h>
#include <api/wnd/wndclass/scrollbar.h>
#include <api/wnd/wndclass/sepwnd.h>
#define SCRLBKGWND_PARENT LabelWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ScrlBkgWnd : public SCRLBKGWND_PARENT {
protected:
/**
Method
@see
@ret
@param
*/
ScrlBkgWnd();
public:
/**
Method
@see
@ret
@param
*/
virtual ~ScrlBkgWnd();
/**
Method
@see
@ret
@param
*/
virtual int onInit();
/**
Method
@see
@ret
@param
*/
virtual int onPaint(Canvas *c);
/**
Method
@see
@ret
@param
*/
virtual void drawBackground(Canvas *canvas);
/**
Method
@see
@ret
@param
*/
virtual int onEraseBkgnd(HDC dc);
/**
Method
@see
@ret
@param
*/
virtual int childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2);
/**
Method
@see
@ret
@param
*/
virtual int onResize();
/**
Method
@see
@ret
@param
*/
virtual void getClientRect(RECT *r);
// virtual void getNonClientRect(RECT *r);
/**
Method
@see
@ret
@param
*/
virtual int getHeaderHeight();
virtual void timerCallback (int id);
/**
Method
@see
@ret
@param
*/
virtual void onHScrollToggle(int set);
/**
Method
@see
@ret
@param
*/
virtual void onVScrollToggle(int set);
/**
Method
@see
@ret
@param
*/
virtual void onSetVisible(int show);
/**
Method
@see
@ret
@param
*/
virtual int wantHScroll() { return 1; }
/**
Method
@see
@ret
@param
*/
virtual int wantVScroll() { return 1; }
/**
Method
@see
@ret
@param
*/
void makeWindowOverlayMask(api_region *r);
/**
Method
@see
@ret
@param
*/
SkinBitmap *getBgBitmap(void);
/**
Method
@see
@ret
@param
*/
void setBgBitmap(const wchar_t *b);
/**
Method
@see
@ret
@param
*/
void setBgColor(ARGB32 rgb);
/**
Method
@see
@ret
@param
*/
virtual ARGB32 getBgColor(void);
/**
Method
@see
@ret
@param
*/
virtual int getContentsWidth(); // not safe to call getclientrect!
/**
Method
@see
@ret
@param
*/
virtual int getContentsHeight(); // not safe to call getclientrect!
/**
Method
@see
@ret
@param
*/
void setLineHeight(int h);
/**
Method
@see
@ret
@param
*/
int getLinesPerPage();
/**
Method
@see
@ret
@param
*/
int getScrollX();
/**
Method
@see
@ret
@param
*/
int getScrollY();
/**
Method
@see
@ret
@param
*/
int getScrollbarWidth();
/**
Method
@see
@ret
@param
*/
virtual void scrollToY(int y, int signal=TRUE);
/**
Method
@see
@ret
@param
*/
virtual void scrollToX(int x, int signal=TRUE);
protected:
virtual void onScrollY(int y) { }
/**
Method
@see
@ret
@param
*/
void setSlidersPosition();
/**
Method
@see
@ret
@param
*/
int needDoubleBuffer();
/**
Method
@see
@ret
@param
*/
bool needHScroll();
/**
Method
@see
@ret
@param
*/
bool needVScroll();
/**
Method
@see
@ret
@param
*/
int getMaxScrollY();
/**
Method
@see
@ret
@param
*/
int getMaxScrollX();
/**
Method
@see
@ret
@param
*/
void updateScrollY(bool smooth=false);
/**
Method
@see
@ret
@param
*/
void updateScrollX(bool smooth=false);
/**
Method
@see
@ret
@param
*/
void smoothScrollToY(int y);
/**
Method
@see
@ret
@param
*/
void smoothScrollToX(int x);
/**
Method
@see
@ret
@param
*/
void updateVScroll(int y);
/**
Method
@see
@ret
@param
*/
void updateHScroll(int x);
AutoSkinBitmap bmp;
int dbbuffer;
bool inDestroy;
ScrollBar hScroll;
ScrollBar vScroll;
SepWnd hSep;
SepWnd vSep;
ARGB32 bgColor;
int scrollX;
int scrollY;
bool needSetSliders;
bool wantsep;
bool wantTileBg;
int lineHeight;
float smoothScrollYInc, smoothScrollXInc;
float smoothScrollYCur, smoothScrollXCur;
int smoothScrollYTimerCount, smoothScrollXTimerCount;
int smoothYTimer, smoothXTimer;
/**
Method
@see
@ret
@param
*/
void killSmoothYTimer();
/**
Method
@see
@ret
@param
*/
void killSmoothXTimer();
double lastratio;
RECT smsqr;
/**
Method
@see
@ret
@param
*/
void _setSlidersPosition();
int in_set_slider_position;
};
#endif
+679
View File
@@ -0,0 +1,679 @@
#include <precomp.h>
#include <bfc/wasabi_std.h>
#include "scrollbar.h"
#include <tataki/canvas/canvas.h>
#include <api/wnd/notifmsg.h>
#include <api/wnd/PaintCanvas.h>
#define TIMER_ID 9871
#define TIMER_ID2 9872
#define FIRST_DELAY 350
#define NEXT_DELAY 75
ScrollBar::ScrollBar() {
leftrgn = NULL;
rightrgn = NULL;
buttonrgn = NULL;
position = 0;
moving = 0;
lefting = 0;
righting = 0;
clicked = 0;
height = DEFAULT_HEIGHT;
buttonx = 0;
shiftleft = 0;
shiftright = 0;
curmouseposition = POS_NONE;
clickmouseposition = POS_NONE;
pageing = 0;
timer = timer2 = 0;
npages = 100;
pageway = PAGE_NONE;
updown = 256;
insetpos = 0;
clickbuttonx = 0;
vertical = 0;
firstdelay = 0;
lastx = lasty = 0;
}
ScrollBar::~ScrollBar() {
deleteResources();
}
void ScrollBar::deleteResources() {
delete leftrgn; leftrgn = NULL;
delete buttonrgn; buttonrgn = NULL;
delete rightrgn; rightrgn = NULL;
}
// this one is inherited
void ScrollBar::freeResources() {
SCROLLBAR_PARENT::freeResources();
deleteResources();
}
void ScrollBar::reloadResources() {
SCROLLBAR_PARENT::reloadResources();
loadBmps();
}
int ScrollBar::onMouseMove (int x, int y) {
SCROLLBAR_PARENT::onMouseMove(x, y);
lastx = x;
lasty = y;
if (clicked && clickmouseposition == POS_BUTTON) {
POINT pt={x,y};
int x;
if (!vertical)
x = pt.x - clickpos.x;
else
x = pt.y - clickpos.y;
RECT r;
getClientRect(&r);
int maxwidth;
if (!vertical)
maxwidth = (r.right-r.left)-(shiftright+shiftleft+bmpbutton.getWidth())+1;
else
maxwidth = (r.bottom-r.top)-(shiftright+shiftleft+bmpbutton.getHeight())+1;
buttonx = MIN(MAX(clickbuttonx + x, 0), maxwidth);
calcPosition();
invalidate();
} else {
int oldposition = curmouseposition;
curmouseposition = getMousePosition();
if (oldposition != curmouseposition) invalidate();
if (curmouseposition != POS_NONE && !getCapture())
beginCapture();
if (curmouseposition == POS_NONE && getCapture() && !clicked && !pageing)
endCapture();
}
return 1;
}
int ScrollBar::getWidth() {
if (!bmpbutton) return 0;
if (!vertical)
return bmpbutton.getHeight();
else
return bmpbutton.getWidth();
return 0;
}
int ScrollBar::getMousePosition() {
int v = POS_NONE;
POINT pt={lastx, lasty};
RECT c;
getClientRect(&c);
pt.x -= c.left;
pt.y -= c.top;
api_region *l, *b, *r;
l = leftrgn->clone();
b = buttonrgn->clone();
if (!vertical)
b->offset(buttonx+shiftleft, 0);
else
b->offset(0, buttonx+shiftleft);
r = rightrgn->clone();
if (!vertical)
r->offset(c.right-c.left-bmpleft.getWidth(), 0);
else
r->offset(0, c.bottom-c.top-bmpleft.getHeight());
if (b->ptInRegion(&pt))
v = POS_BUTTON;
if (l->ptInRegion(&pt))
v = POS_LEFT;
if (r->ptInRegion(&pt))
v = POS_RIGHT;
leftrgn->disposeClone(l);
buttonrgn->disposeClone(b);
rightrgn->disposeClone(r);
return v;
}
int ScrollBar::onLeftButtonDown(int x, int y) {
clickmouseposition = getMousePosition();
if (!pageing && clickmouseposition != POS_NONE) {
clicked = 1;
if (clickmouseposition == POS_LEFT || clickmouseposition == POS_RIGHT)
handleUpDown();
if (clickmouseposition) {
clickpos.x = lastx;
clickpos.y = lasty;
clickbuttonx = buttonx;
}
} else {
clicked = 0;
pageing = 1;
handlePageUpDown();
}
invalidate();
return 1;
}
void ScrollBar::handleUpDown() {
setTimer(TIMER_ID2, FIRST_DELAY);
timer2 = 1;
firstdelay = 1;
checkUpDown();
}
int ScrollBar::checkUpDown() {
if (!clicked) {
if (timer2) {
killTimer(TIMER_ID2);
timer2 = 0;
return 1;
}
}
if (getMousePosition() == clickmouseposition)
upDown(clickmouseposition);
return 1;
}
void ScrollBar::handlePageUpDown() {
setTimer(TIMER_ID, FIRST_DELAY);
timer = 1;
firstdelay = 1;
checkPageUpDown();
}
int ScrollBar::checkPageUpDown() {
if (!pageing) {
if (timer) {
killTimer(TIMER_ID);
timer = 0;
pageway = PAGE_NONE;
return 1;
}
}
POINT pt={lastx,lasty};
RECT c;
getClientRect(&c);
pt.x -= c.left;
pt.y -= c.top;
if (!vertical) {
int middlebutton = shiftleft + buttonx + bmpbutton.getWidth()/2;
api_region *r = buttonrgn->clone();
r->offset(buttonx+shiftleft, 0);
if (pt.x > middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_DOWN)
pageUp();
if (pt.x < middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_UP)
pageDown();
buttonrgn->disposeClone(r);
} else {
int middlebutton = shiftleft + buttonx + bmpbutton.getHeight()/2;
api_region *r = buttonrgn->clone();
r->offset(0, buttonx+shiftleft);
if (pt.y > middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_DOWN)
pageUp();
if (pt.y < middlebutton && !r->ptInRegion(&pt) && pageway != PAGE_UP)
pageDown();
buttonrgn->disposeClone(r);
}
return 1;
}
int ScrollBar::onLeftButtonUp(int x, int y) {
clicked = 0;
clickmouseposition = POS_NONE;
curmouseposition = POS_NONE;
onMouseMove(x,y);
if (pageing) {
pageing = 0;
checkPageUpDown();
}
onSetFinalPosition();
invalidate();
return 1;
}
int ScrollBar::onRightButtonDown(int x, int y) {
return 1;
}
int ScrollBar::onRightButtonUp(int x, int y) {
return 1;
}
int ScrollBar::onMouseWheelUp(int clicked, int lines) {
return 1;
}
int ScrollBar::onMouseWheelDown(int clicked, int lines) {
return 1;
}
int ScrollBar::onPaint(Canvas *canvas) {
AutoSkinBitmap &thisleft = curmouseposition == POS_LEFT ? (clicked ? bmplpressed : bmplhilite) : bmpleft;
AutoSkinBitmap &thisbutton = curmouseposition == POS_BUTTON ? (clicked ? bmpbpressed : bmpbhilite) : bmpbutton;
AutoSkinBitmap &thisright = curmouseposition == POS_RIGHT ? (clicked ? bmprpressed : bmprhilite) : bmpright;
if (curmouseposition != clickmouseposition && clicked) {
thisleft = bmpleft;
thisbutton = bmpbutton;
thisright = bmpright;
}
RECT r;
PaintBltCanvas paintcanvas;
if (canvas == NULL) {
if (!paintcanvas.beginPaint(this)) return 0;
canvas = &paintcanvas;
}
SCROLLBAR_PARENT::onPaint(canvas);
getClientRect(&r);
renderBaseTexture(canvas, r);
if (!vertical) {
RECT c;
c.left = r.left;
c.right = r.left;
c.top = r.top;
c.bottom = r.bottom;
if (bmpbackgroundleft.getBitmap()) {
c.right = c.left + bmpbackgroundleft.getWidth();
bmpbackgroundleft.getBitmap()->stretchToRectAlpha(canvas, &c);
}
int l = c.right;
c.left = r.right;
c.right = r.right;
if (bmpbackgroundright.getBitmap()) {
c.left = r.right - bmpbackgroundright.getWidth();
bmpbackgroundright.getBitmap()->stretchToRectAlpha(canvas, &c);
}
c.right = c.left;
c.left = l;
if (bmpbackgroundmiddle.getBitmap()) {
bmpbackgroundmiddle.getBitmap()->stretchToRectAlpha(canvas, &c);
}
c.left = r.left + buttonx+shiftleft;
c.top = r.top + 0;
c.right = r.left + buttonx+thisbutton.getWidth()+shiftleft;
c.bottom = r.top + getWidth();
thisbutton.stretchToRectAlpha(canvas, &c);
c.left = r.left;
c.top = r.top;
c.right = r.left + thisleft.getWidth();
c.bottom = r.top + getWidth();
thisleft.stretchToRectAlpha(canvas, &c);
c.left = r.right-thisright.getWidth();
c.top = r.top;
c.right = r.right;
c.bottom = r.top+getWidth();
thisright.stretchToRectAlpha(canvas, &c);
} else {
RECT c;
c.top = r.top;
c.bottom = r.top;
c.left = r.left;
c.right = r.right;
if (bmpbackgroundleft.getBitmap()) {
c.bottom = c.top + bmpbackgroundleft.getHeight();
bmpbackgroundleft.getBitmap()->stretchToRectAlpha(canvas, &c);
}
int l = c.bottom;
c.top = r.bottom;
c.bottom = r.bottom;
if (bmpbackgroundright.getBitmap()) {
c.top = r.bottom - bmpbackgroundright.getHeight();
bmpbackgroundright.getBitmap()->stretchToRectAlpha(canvas, &c);
}
c.bottom = c.top;
c.top = l;
if (bmpbackgroundmiddle.getBitmap()) {
bmpbackgroundmiddle.getBitmap()->stretchToRectAlpha(canvas, &c);
}
c.left = r.right - thisleft.getWidth();
c.top = r.top+buttonx + shiftleft;
c.right = r.right;
c.bottom = r.top+buttonx+thisbutton.getHeight() + shiftleft;
thisbutton.stretchToRectAlpha(canvas, &c);
c.left = r.right - thisleft.getWidth();
c.top = r.top;
c.right = r.right;
c.bottom = r.top+thisleft.getHeight();
thisleft.stretchToRectAlpha(canvas, &c);
c.left = r.right-thisright.getWidth();
c.top = r.bottom-thisright.getHeight();
c.right = r.right;
c.bottom = r.bottom;
thisright.stretchToRectAlpha(canvas, &c);
}
return 1;
}
int ScrollBar::getHeight() {
return height;
}
void ScrollBar::setHeight(int newheight) {
height = newheight;
}
int ScrollBar::onResize() {
calcXPosition();
invalidate();
return 1;
}
int ScrollBar::onInit() {
SCROLLBAR_PARENT::onInit();
return 1;
}
void ScrollBar::setBitmaps(wchar_t *left, wchar_t *lpressed, wchar_t *lhilite,
wchar_t *right, wchar_t *rpressed, wchar_t *rhilite,
wchar_t *button, wchar_t *bpressed, wchar_t *bhilite) {
deleteResources();
bmpleft = left;
bmplpressed = lpressed;
bmplhilite = lhilite;
bmpright = right;
bmprpressed = rpressed;
bmprhilite = rhilite;
bmpbutton = button;
bmpbpressed = bpressed;
bmpbhilite = bhilite;
loadBmps();
}
void ScrollBar::setBackgroundBitmaps(const wchar_t *left, const wchar_t *middle, const wchar_t *right) {
bmpbackgroundleft = left;
bmpbackgroundmiddle = middle;
bmpbackgroundright = right;
}
void ScrollBar::loadBmps() {
if (bmpleft.getBitmap()) leftrgn = new RegionI(bmpleft);
if (bmpbutton.getBitmap()) buttonrgn = new RegionI(bmpbutton);
if (bmpright.getBitmap()) rightrgn = new RegionI(bmpright);
calcOverlapping();
calcXPosition();
}
void ScrollBar::setPosition(int pos) {
setPrivatePosition(pos, FALSE);
}
void ScrollBar::setPrivatePosition(int pos, bool signal, bool smooth) {
if (insetpos) return; // helps stupid people (like me)
insetpos = 1;
position = MIN(SCROLLBAR_FULL, pos);
position = MAX(0, position);
calcXPosition();
if (signal) onSetPosition(smooth);
if (isInited() && isVisible())
invalidate();
insetpos = 0;
}
int ScrollBar::getPosition() {
return position;
}
int ScrollBar::onSetPosition(bool smooth) {
notifyParent(ChildNotify::SCROLLBAR_SETPOSITION, smooth);
return 1;
}
int ScrollBar::onSetFinalPosition() {
notifyParent(ChildNotify::SCROLLBAR_SETFINALPOSITION);
return 1;
}
void ScrollBar::calcOverlapping() {
if (!vertical) {
shiftleft = bmpleft.getWidth();
if (leftrgn && buttonrgn) {
int i;
for (i=shiftleft;i>=0;i--) {
api_region *reg = buttonrgn->clone();
reg->offset(i, 0);
if (leftrgn->doesIntersectRgn(reg)) {
i++;
buttonrgn->disposeClone(reg);
break;
}
buttonrgn->disposeClone(reg);
}
if (i >= 0)
shiftleft = i;
}
shiftright = bmpright.getWidth();
if (rightrgn && buttonrgn) {
int i;
for (i=0;i>=-shiftright;i--) {
api_region *reg = rightrgn->clone();
reg->offset(i+bmpbutton.getWidth(), 0);
if (reg->doesIntersectRgn(buttonrgn)) {
i++;
rightrgn->disposeClone(reg);
break;
}
rightrgn->disposeClone(reg);
}
if (i >= -shiftright)
shiftright += i;
}
} else {
shiftleft = bmpleft.getHeight();
if (leftrgn && buttonrgn) {
int i;
for (i=shiftleft;i>=0;i--) {
api_region *reg = buttonrgn->clone();
reg->offset(0, i);
if (leftrgn->doesIntersectRgn(reg)) {
i++;
buttonrgn->disposeClone(reg);
break;
}
buttonrgn->disposeClone(reg);
}
if (i >= 0)
shiftleft = i;
}
shiftright = bmpright.getHeight();
if (rightrgn && buttonrgn) {
int i;
for (i=0;i>=-shiftright;i--) {
api_region *reg = rightrgn->clone();
reg->offset(0, i+bmpbutton.getHeight());
if (reg->doesIntersectRgn(buttonrgn)) {
i++;
rightrgn->disposeClone(reg);
break;
}
rightrgn->disposeClone(reg);
}
if (i >= -shiftright)
shiftright += i;
}
}
}
void ScrollBar::calcXPosition() {
if (!isInited()) return;
RECT r;
getClientRect(&r);
int maxwidth;
if (!vertical)
maxwidth = (r.right-r.left)-(bmpbutton.getWidth()+shiftleft+shiftright)+1;
else
maxwidth = (r.bottom-r.top)-(bmpbutton.getHeight()+shiftleft+shiftright)+1;
int oldx = buttonx;
buttonx = (int)(((float)getPosition() / SCROLLBAR_FULL) * maxwidth);
if (buttonx != oldx)
invalidate();
}
void ScrollBar::calcPosition() {
if (!isInited()) return;
RECT r;
getClientRect(&r);
int maxwidth;
if (!vertical)
maxwidth = r.right-r.left-(bmpbutton.getWidth()+shiftleft+shiftright)+1;
else
maxwidth = r.bottom-r.top-(bmpbutton.getHeight()+shiftleft+shiftright)+1;
setPrivatePosition((int)((float)buttonx / maxwidth * SCROLLBAR_FULL));
//invalidate();
}
void ScrollBar::timerCallback(int id) {
switch (id) {
case TIMER_ID:
if (firstdelay) {
killTimer(TIMER_ID);
setTimer(TIMER_ID, NEXT_DELAY);
timer = 1;
firstdelay = 0;
}
checkPageUpDown();
break;
case TIMER_ID2:
if (firstdelay) {
killTimer(TIMER_ID2);
setTimer(TIMER_ID2, NEXT_DELAY);
timer2 = 1;
firstdelay = 0;
}
checkUpDown();
break;
default:
SCROLLBAR_PARENT::timerCallback(id);
}
}
// FG> smooth scrolling forced on, sorry, microsoft does it too so the user perceives IE scrolling as faster than it actually is
// eventho they tell you "The smooth-scrolling effect for list boxes should be disabled when this setting is FALSE. Your application must do this if it creates customized list boxes", they
// break their own rule so people don't bitch too much. ergo there is no reason we should not do that too.
int ScrollBar::pageUp() {
pageway = PAGE_UP;
setPrivatePosition((int)MAX(0.f, (float)getPosition() + (float)SCROLLBAR_FULL / (npages-1)), TRUE, 1/*Std::osparam_getSmoothScroll()*/);
return 1;
};
int ScrollBar::pageDown() {
pageway = PAGE_DOWN;
setPrivatePosition((int)MIN((float)SCROLLBAR_FULL, (float)getPosition() - (float)SCROLLBAR_FULL / (npages-1)), TRUE, 1/*Std::osparam_getSmoothScroll()*/);
return 1;
};
void ScrollBar::setNPages(int n) {
//ASSERT(n >= 2);
if (n < 2) n = 2;
npages = n;
}
void ScrollBar::gotoPage(int page) {
page = MIN(page, npages-1);
page = MAX(page, 0);
setPrivatePosition((int)((float)SCROLLBAR_FULL / (npages-1) * page), TRUE, FALSE);
}
void ScrollBar::setUpDownValue(int newupdown) {
updown = newupdown;
}
int ScrollBar::upDown(int which) {
switch (which) {
case POS_LEFT:
setPrivatePosition(getPosition()-updown);
break;
case POS_RIGHT:
setPrivatePosition(getPosition()+updown);
break;
}
return 1;
}
void ScrollBar::setVertical(bool isvertical) {
vertical = isvertical;
calcOverlapping();
if (isInited())
invalidate();
}
+423
View File
@@ -0,0 +1,423 @@
#ifndef __SCROLLBAR_H
#define __SCROLLBAR_H
#include <api/wnd/virtualwnd.h>
#include <tataki/region/region.h>
#include <api/wnd/usermsg.h>
#include <tataki/bitmap/autobitmap.h>
#define SCROLLBAR_FULL 65535
#define POS_NONE 0
#define POS_LEFT 1
#define POS_BUTTON 2
#define POS_RIGHT 3
#define PAGE_NONE 0
#define PAGE_DOWN 1
#define PAGE_UP 2
#define DEFAULT_HEIGHT 16
#define SCROLLBAR_PARENT VirtualWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class ScrollBar : public SCROLLBAR_PARENT {
public:
/**
Method
@see
@ret
@param
*/
ScrollBar();
/**
Method
@see
@ret
@param
*/
virtual ~ScrollBar();
virtual int onMouseMove (int x, int y);
/**
Method
@see
@ret
@param
*/
virtual int onLeftButtonDown(int x, int y);
/**
Method
@see
@ret
@param
*/
virtual int onLeftButtonUp(int x, int y);
/**
Method
@see
@ret
@param
*/
virtual int onRightButtonDown(int x, int y);
/**
Method
@see
@ret
@param
*/
virtual int onRightButtonUp(int x, int y);
/**
Method
@see
@ret
@param
*/
virtual int onMouseWheelUp(int clicked, int lines);
/**
Method
@see
@ret
@param
*/
virtual int onMouseWheelDown(int clicked, int lines);
/**
Method
@see
@ret
@param
*/
virtual int onPaint(Canvas *canvas);
/**
Method
@see
@ret
@param
*/
virtual int onResize();
/**
Method
@see
@ret
@param
*/
virtual int onInit();
/**
Method
@see
@ret
@param
*/
virtual void timerCallback(int id);
/**
Method
@see
@ret
@param
*/
virtual int wantDoubleClicks() { return 0; };
virtual int onSetPosition(bool smooth=false);
virtual int onSetFinalPosition();
void setBitmaps(wchar_t *left, wchar_t *lpressed, wchar_t *lhilite,
wchar_t *right, wchar_t *rpressed, wchar_t *rhilite,
wchar_t *button, wchar_t *bpressed, wchar_t *bhilite);
void setBackgroundBitmaps(const wchar_t *left, const wchar_t *middle, const wchar_t *right);
void setPosition(int pos);
/**
Method
@see
@ret
@param
*/
int getPosition();
/**
Method
@see
@ret
@param
*/
int getHeight();
/**
Method
@see
@ret
@param
*/
void setHeight(int newheight);
/**
Method
@see
@ret
@param
*/
void setNPages(int n);
/**
Method
@see
@ret
@param
*/
void gotoPage(int n);
/**
Method
@see
@ret
@param
*/
void setUpDownValue(int newupdown);
/**
Method
@see
@ret
@param
*/
void setVertical(bool isvertical);
/**
Method
@see
@ret
@param
*/
int getWidth();
/**
Method
@see
@ret
@param
*/
virtual void freeResources();
/**
Method
@see
@ret
@param
*/
virtual void reloadResources();
private:
/**
Method
@see
@ret
@param
*/
void deleteResources();
/**
Method
@see
@ret
@param
*/
int getMousePosition();
/**
Method
@see
@ret
@param
*/
void calcOverlapping();
/**
Method
@see
@ret
@param
*/
void calcXPosition();
/**
Method
@see
@ret
@param
*/
void calcPosition();
/**
Method
@see
@ret
@param
*/
void handlePageUpDown();
/**
Method
@see
@ret
@param
*/
int checkPageUpDown();
/**
Method
@see
@ret
@param
*/
void handleUpDown();
/**
Method
@see
@ret
@param
*/
int checkUpDown();
/**
Method
@see
@ret
@param
*/
int pageUp();
/**
Method
@see
@ret
@param
*/
int pageDown();
/**
Method
@see
@ret
@param
*/
int upDown(int which);
/**
Method
@see
@ret
@param
*/
void setPrivatePosition(int pos, bool signal=true, bool smooth=false);
/**
Method
@see
@ret
@param
*/
void loadBmps();
AutoSkinBitmap bmpleft, bmplpressed, bmplhilite,
bmpright, bmprpressed, bmprhilite,
bmpbutton, bmpbpressed, bmpbhilite,
bmpbackgroundleft, bmpbackgroundmiddle, bmpbackgroundright;
RegionI *leftrgn, *rightrgn, *buttonrgn;
int position;
int moving;
int lefting;
int righting;
int clicked;
int buttonx;
int curmouseposition;
int clickmouseposition;
int height;
int shiftleft, shiftright;
POINT clickpos;
int clickbuttonx;
int pageing;
int firstdelay;
int timer;
int npages;
int pageway;
int updown;
int timer2;
int insetpos;
int vertical;
int lastx, lasty;
};
#endif
+63
View File
@@ -0,0 +1,63 @@
#include <precomp.h>
#include <tataki/bitmap/bitmap.h>
#include <api/wnd/basewnd.h>
#include "sepwnd.h"
#include <tataki/canvas/canvas.h>
#include <api/wnd/PaintCanvas.h>
SepWnd::SepWnd() {
bitmap = NULL;
orientation = SEP_UNKNOWN;
}
SepWnd::~SepWnd() {
if (bitmap) delete bitmap;
}
int SepWnd::onPaint(Canvas *canvas) {
PaintBltCanvas paintcanvas;
if (canvas == NULL) {
if (!paintcanvas.beginPaintNC(this)) return 0;
canvas = &paintcanvas;
}
if (!bitmap) {
switch (orientation) {
case SEP_VERTICAL:
bitmap = new SkinBitmap(L"studio.FrameVerticalDivider");
break;
case SEP_HORIZONTAL:
bitmap = new SkinBitmap(L"studio.FrameHorizontalDivider");
break;
case SEP_UNKNOWN:
return 1;
}
ASSERT(bitmap != NULL);
}
RECT r;
getClientRect(&r);
RenderBaseTexture(canvas, r);
if (bitmap) {
bitmap->stretchToRectAlpha(canvas, &r, 128);
}
return 1;
}
int SepWnd::setOrientation(int which) {
orientation = which;
return 1;
}
int SepWnd::onInit() {
SEPWND_PARENT::onInit();
return 1;
}
void SepWnd::freeResources() {
SEPWND_PARENT::freeResources();
if (bitmap) delete bitmap;
bitmap = NULL;
}
+27
View File
@@ -0,0 +1,27 @@
#ifndef __SEPWND_H
#define __SEPWND_H
#include <tataki/bitmap/bitmap.h>
#include <api/wnd/virtualwnd.h>
#define SEP_UNKNOWN -1
#define SEP_VERTICAL 0
#define SEP_HORIZONTAL 1
#define SEPWND_PARENT VirtualWnd
class SepWnd : public VirtualWnd {
public:
SepWnd();
~SepWnd();
virtual int onPaint(Canvas *c);
virtual int setOrientation(int which);
virtual int onInit();
virtual void freeResources();
private:
SkinBitmap *bitmap;
int orientation;
};
#endif
+705
View File
@@ -0,0 +1,705 @@
#include <precomp.h>
#include "slider.h"
#include <tataki/canvas/canvas.h>
#include <api/wnd/notifmsg.h>
#include <api/wnd/PaintCanvas.h>
#define DEFAULT_THUMBWIDTH 16
#define DEFAULT_THUMBHEIGHT 16
SliderWnd::SliderWnd()
{
seeking = 0;
enabled = 1;
hilite = 0;
pos = 0;
oldpos = -1;
thumbwidth = DEFAULT_THUMBWIDTH;
captured = 0;
xShift = 0;
yShift = 0;
base_texture = NULL;
use_base_texture = 0;
no_default_background = 0;
drawOnBorders = 0;
hotPosition = -1;
origPos = 0;
vertical = 0;
thumbCentered = 1;
thumbOffset = 0;
thumbStretched = 0;
hotposrange = -1;
setLimits(START, END);
}
SliderWnd::~SliderWnd()
{}
int SliderWnd::onPaint(Canvas *canvas)
{
if (canvas == NULL)
{
PaintBltCanvas paintcanvas;
if (!paintcanvas.beginPaint(this))
return 0;
SliderWnd::onPaint(&paintcanvas);
}
SLIDERWND_PARENT::onPaint(canvas);
RECT r, origr;
getClientRect(&r);
origr = r;
if (use_base_texture)
{
if (!base_texture)
{
renderBaseTexture(canvas, r);
}
else
{
RECT cr;
cr.left = xShift;
cr.top = yShift;
cr.right = cr.left + (r.right - r.left);
cr.bottom = cr.top + (r.bottom - r.top);
base_texture->blitToRect(canvas, &cr, &r);
}
}
if (vertical)
{
RECT br;
br.left = r.left;
br.right = r.right;
if (left.getBitmap())
{
br.top = r.top;
br.bottom = left.getHeight();
left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
if (right.getBitmap())
{
br.top = r.bottom - right.getHeight();
br.bottom = r.bottom;
right.stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
if (middle.getBitmap())
{
br.top = r.top + (left.getBitmap() ? left.getHeight() : 0);
br.bottom = r.bottom - (right.getBitmap() ? right.getHeight() : 0);
middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
}
else
{
RECT br;
br.top = r.top;
br.bottom = r.bottom;
if (left.getBitmap())
{
br.left = r.left;
br.right = br.left + left.getWidth();
left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
if (right.getBitmap())
{
br.left = r.right - right.getWidth();
br.right = r.right;
right.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
if (middle.getBitmap())
{
br.left = r.left + (left.getBitmap() ? left.getWidth() : 0);
br.right = r.right - (right.getBitmap() ? right.getWidth() : 0);
middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
}
}
if (vertical)
{
int w = (r.bottom - r.top) - thumbHeight();
// ASSERT(w > 0); // if the control paints off the edge of the screen, this will needlessly assert.
if (w < 0) w = 0;
r.top += (pos * w) / length;
r.bottom = r.top + thumbHeight();
if (!thumbStretched)
{
if (!thumbCentered)
{
r.left = origr.left + thumbOffset;
r.right = origr.left + thumbWidth() + thumbOffset;
}
else
{
int w = ((r.right - r.left) - thumbWidth()) / 2;
r.left = origr.left + w + thumbOffset;
r.right = origr.right - w + thumbOffset;
}
}
else
{
r.left = origr.left;
r.right = origr.right;
}
}
else
{
// offset for left bitmap
if (!drawOnBorders)
{
if (left.getBitmap() != NULL) r.left += left.getWidth();
if (right.getBitmap() != NULL) r.right -= right.getWidth();
}
int w = (r.right - r.left) - thumbWidth();
if (w < 0) w = 0;
r.left += (pos * w) / length;
r.right = r.left + thumbWidth();
if (r.right > origr.right)
{
r.left -= r.right - origr.right;
r.right = origr.right;
}
if (!thumbStretched)
{
int thumbh = thumb.getBitmap() ? thumb.getHeight() : DEFAULT_THUMBWIDTH;
if (thumbCentered)
{
int h = ((r.bottom - r.top) - thumbh) / 2;
r.top = origr.top + h;
r.bottom = origr.bottom - h;
}
else
{
r.top = origr.top + thumbOffset;
r.bottom = origr.top + thumbh + thumbOffset;
}
}
else
{
r.top = origr.top;
r.bottom = origr.bottom;
}
}
SkinBitmap *sb = getSeekStatus() ? (thumbdown.getBitmap() ? thumbdown.getBitmap() : thumb.getBitmap()) : ((hilite && thumbhilite.getBitmap()) ? thumbhilite.getBitmap() : thumb.getBitmap());
if (sb != NULL)
sb->stretchToRectAlpha(canvas, &r, getPaintingAlpha());
else
canvas->fillRect(&r, RGB(255, 0, 0));
return 1;
}
int SliderWnd::onInit()
{
SLIDERWND_PARENT::onInit();
if (!no_default_background)
{
if (vertical)
{
// Please note that these bitmaps here do not yet exist.
if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.vertical.top");
if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.vertical.middle");
if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.vertical.bottom");
if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.vertical.button");
if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.vertical.button.pressed");
}
else
{
if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.horizontal.left");
if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.horizontal.middle");
if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.horizontal.right");
if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.horizontal.button");
if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.horizontal.button.pressed");
}
}
return 1;
}
int SliderWnd::onLeftButtonDown(int x, int y)
{
SLIDERWND_PARENT::onLeftButtonDown(x, y);
if (!enabled) return 0;
seeking = 1;
origPos = 0;
RECT r;
getClientRect(&r);
if (vertical)
{
int w = (r.bottom - r.top) - thumbHeight();
if (w < 0) w = 0;
r.top += (pos * w) / length;
origPos = (y - r.top) - 1;
/*if(origPos<0 || origPos>thumbHeight())*/ origPos = (thumbHeight() / 2) - 2;
}
else
{
if (!drawOnBorders)
{
if (left.getBitmap() != NULL) r.left += left.getWidth();
if (right.getBitmap() != NULL) r.right -= right.getWidth();
}
int w = (r.right - r.left) - thumbWidth();
if (w < 0) w = 0;
r.left += (pos * w) / length;
origPos = (x - r.left) - 1;
if (origPos < 0 || origPos > thumbWidth()) origPos = (thumbWidth() / 2) - 2;
}
if (!captured)
{
captured = 1;
beginCapture();
}
oldpos = pos;
onMouseMove(x, y);
return 1;
}
//FG>
//removed cross-hierarchy deletion (crashs due to ancestor in common.dll trying to delete pointers in a different
//heap scope than the one in which they were allocated)
void SliderWnd::setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp)
{
setThumbBmp(thumbbmp);
setThumbDownBmp(thumbdownbmp);
setThumbHiliteBmp(thumbhighbmp);
setLeftBmp(leftbmp);
setRightBmp(rightbmp);
setMiddleBmp(middlebmp);
}
void SliderWnd::setLeftBmp(const wchar_t *name)
{
left = name;
invalidate();
}
void SliderWnd::setMiddleBmp(const wchar_t *name)
{
middle = name;
invalidate();
}
void SliderWnd::setRightBmp(const wchar_t *name)
{
right = name;
invalidate();
}
void SliderWnd::setThumbBmp(const wchar_t *name)
{
thumb = name;
invalidate();
}
void SliderWnd::setThumbDownBmp(const wchar_t *name)
{
thumbdown = name;
invalidate();
}
void SliderWnd::setThumbHiliteBmp(const wchar_t *name)
{
thumbhilite = name;
invalidate();
}
SkinBitmap *SliderWnd::getLeftBitmap()
{
return left;
}
SkinBitmap *SliderWnd::getRightBitmap()
{
return right;
}
SkinBitmap *SliderWnd::getMiddleBitmap()
{
return middle;
}
SkinBitmap *SliderWnd::getThumbBitmap()
{
return thumb;
}
SkinBitmap *SliderWnd::getThumbDownBitmap()
{
return thumbdown;
}
SkinBitmap *SliderWnd::getThumbHiliteBitmap()
{
return thumbhilite;
}
int SliderWnd::getWidth()
{
if (vertical)
return (getThumbBitmap() ? getThumbBitmap()->getWidth() : 0);
else
{
return 64;
}
}
int SliderWnd::getHeight()
{
if (!vertical)
return (getThumbBitmap() ? getThumbBitmap()->getHeight() : 0);
else
{
return 64;
}
}
void SliderWnd::setEnable(int en)
{
if (enabled != en) invalidate();
enabled = en;
}
int SliderWnd::getEnable(void)
{
return enabled;
}
void SliderWnd::setPosition(int newpos, int wantcb)
{
if (newpos < minlimit) newpos = minlimit;
else if (newpos > maxlimit) newpos = maxlimit;
if (vertical) pos = maxlimit - newpos;
else /* horizontal */ pos = newpos - minlimit;
if (wantcb)
onSetPosition();
invalidate();
}
int SliderWnd::onMouseMove(int x, int y)
{
int p, w, mouseover;
SLIDERWND_PARENT::onMouseMove(x, y);
POINT po = {x, y};
clientToScreen(&po);
mouseover = (WASABI_API_WND->rootWndFromPoint(&po) == this);
if (mouseover && !seeking && !captured)
{
beginCapture();
captured = 1;
onEnterArea();
}
int lasthilite = hilite;
hilite = enabled && mouseover;
if (hilite != lasthilite)
{
if (!mouseover && !seeking && captured)
{
endCapture();
captured = 0;
onLeaveArea();
invalidate();
return 0;
}
invalidate();
}
if (!enabled) return 1;
RECT r, origr;
getClientRect(&r);
x -= r.left;
y -= r.top;
origr = r;
if (vertical)
{
w = (r.bottom - r.top) - thumbHeight();
// p = (y - (r.top-origr.top)) - (thumbHeight()/2-2);
p = (y - (r.top - origr.top)) - origPos;
}
else
{
if (!drawOnBorders)
{
if (left != NULL) r.left += left.getWidth();
if (right != NULL) r.right -= right.getWidth();
}
w = (r.right - r.left) - thumbWidth();
// p = (x - (r.left - origr.left)) - (thumbWidth()/2-2);
p = (x - (r.left - origr.left)) - origPos;
}
if (seeking)
{
pos = (p * length) / w;
if (pos < 0) pos = 0;
else if (pos > length) pos = length;
if (hotPosition != -1)
{
int a, c;
if (vertical) a = r.bottom - r.top;
else a = r.right - r.left;
c = getHotPosRange();
if (c == -1)
{
int b = (int)(a * 0.075);
c = (b * length) / a;
}
/**
EQBand: minlimit -127, maxlimit 127, hotpos 0
PanBar: minlimit 0, maxlimit 225, hotpos 127
VSliders pos starts from top by 0 (winamp behaviour reversed!)
*/
if (vertical)
{
//if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
if ((maxlimit - pos) > (hotPosition - c) && (maxlimit - pos) < (hotPosition + c)) pos = hotPosition - minlimit; // Hehe, now it works ;)
}
else
{
if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
//if ((pos - maxlimit)> (hotPosition - c) && (pos - maxlimit) < (hotPosition + c)) pos = hotPosition - minlimit;
}
}
onSetPosition();
invalidate();
}
return 1;
}
void SliderWnd::onCancelCapture()
{
SLIDERWND_PARENT::onCancelCapture();
if (seeking && captured)
abort();
}
int SliderWnd::onLeftButtonUp(int x, int y)
{
SLIDERWND_PARENT::onLeftButtonUp(x, y);
int wasseeking = seeking;
seeking = 0;
captured = 0;
oldpos = -1;
endCapture();
if (wasseeking)
onSetFinalPosition();
invalidate();
return 1;
}
int SliderWnd::onRightButtonDown(int x, int y)
{
SLIDERWND_PARENT::onRightButtonDown(x, y);
if (seeking && captured)
{
abort();
}
return 1;
}
int SliderWnd::onChar(unsigned int c)
{
SLIDERWND_PARENT::onChar(c);
if (seeking && captured && (c == 27))
{
abort();
}
return 1;
}
int SliderWnd::onSetPosition()
{
if (!isInited()) return 0;
notifyParent(ChildNotify::SLIDER_INTERIM_POSITION, getSliderPosition());
return 0;
}
int SliderWnd::onSetFinalPosition()
{
if (!isInited()) return 0;
notifyParent(ChildNotify::SLIDER_FINAL_POSITION, getSliderPosition());
return 0;
}
int SliderWnd::getSliderPosition()
{
if (vertical) return maxlimit -pos;
else return pos + minlimit;
}
int SliderWnd::getSeekStatus()
{
return seeking;
}
int SliderWnd::thumbWidth()
{
if (thumb.getBitmap() == NULL) return DEFAULT_THUMBWIDTH;
return thumb.getWidth();
}
int SliderWnd::thumbHeight()
{
if (thumb.getBitmap() == NULL) return DEFAULT_THUMBHEIGHT;
return thumb.getHeight();
}
void SliderWnd::setUseBaseTexture(int useit)
{
use_base_texture = useit;
invalidate();
}
void SliderWnd::setBaseTexture(SkinBitmap *bmp, int x, int y)
{
base_texture = bmp;
use_base_texture = TRUE;
xShift = x;
yShift = y;
invalidate();
}
void SliderWnd::setNoDefaultBackground(int no)
{
no_default_background = no;
}
void SliderWnd::setDrawOnBorders(int draw)
{
drawOnBorders = draw;
}
void SliderWnd::onEnterArea()
{
SLIDERWND_PARENT::onEnterArea();
}
void SliderWnd::onLeaveArea()
{
SLIDERWND_PARENT::onLeaveArea();
}
void SliderWnd::setOrientation(int o)
{
vertical = o;
}
void SliderWnd::setHotPosition(int h)
{
hotPosition = h;
}
void SliderWnd::setThumbCentered(int c)
{
thumbCentered = c;
}
void SliderWnd::setThumbStretched(int c)
{
thumbStretched = c;
}
void SliderWnd::setThumbOffset(int o)
{
thumbOffset = o;
}
void SliderWnd::abort()
{
if (oldpos != -1)
{
seeking = 0;
captured = 0;
endCapture();
pos = oldpos;
onSetPosition();
invalidate();
oldpos = -1;
}
return ;
}
void SliderWnd::setLimits(int pminlimit, int pmaxlimit)
{
minlimit = pminlimit;
maxlimit = pmaxlimit;
length = maxlimit - minlimit;
}
int SliderWnd::onKeyDown(int vkcode)
{
switch (vkcode)
{
case VK_LEFT: move_left(Std::keyModifier(STDKEY_CONTROL)); return 1;
case VK_RIGHT: move_right(Std::keyModifier(STDKEY_CONTROL)); return 1;
case VK_HOME: move_start(); return 1;
case VK_END: move_end(); return 1;
default: return SLIDERWND_PARENT::onKeyDown(vkcode);
}
}
void SliderWnd::move_left(int bigstep)
{
int pos = getSliderPosition();
if (!bigstep) pos--; else pos -= (ABS(maxlimit - minlimit) / 10);
if (pos < minlimit) pos = minlimit;
setPosition(pos);
}
void SliderWnd::move_right(int bigstep)
{
int pos = getSliderPosition();
if (!bigstep)
pos++;
else
pos += (ABS(maxlimit - minlimit) / 10);
if (pos > maxlimit)
pos = maxlimit;
setPosition(pos);
}
void SliderWnd::move_start()
{
setPosition(minlimit);
}
void SliderWnd::move_end()
{
setPosition(maxlimit);
}
+451
View File
@@ -0,0 +1,451 @@
#ifndef _SLIDER_H
#define _SLIDER_H
#include <bfc/common.h>
#include <tataki/bitmap/autobitmap.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#define SLIDERWND_PARENT GuiObjectWnd
/**
Slider style control.
@short Slider style control.
@author Nullsoft
@ver 1.0
*/
class SliderWnd : public SLIDERWND_PARENT
{
public:
/**
Sets the defaults for the slider. Defaults to a horizontal
slider with the thumb in the center and is enabled.
*/
SliderWnd();
/**
Nothing is handled by the destructor.
*/
virtual ~SliderWnd();
/**
Event is triggered when the window requires a repaint.
Override this to implement your own behavior.
Paints the slider on canvas according to current
state of the slider.
@ret 0, Failed; 1, Success;
@param canvas The canvas on which to paint.
*/
virtual int onPaint(Canvas *canvas);
/**
Event is triggered when the left mouse button is pressed while
the slider has focus. Override this to implement your
own behavior.
@ret
@param x X coordinate of the mouse pointer.
@param y Y coordinate of the mouse pointer.
*/
virtual int onLeftButtonDown(int x, int y);
/**
Event is triggered when the mouse has capture on the slider
and is being moved. Override this to implement your own
behavior.
@ret 0, Failed; 1, Success;
@param x The X position of the mouse.
@param y The Y position of the mouse.
*/
virtual int onMouseMove(int x, int y); // only called when mouse captured
/**
Event is triggered when the left mouse button is released.
Note that the mouse button must have been previously pressed
for this event to happen. Override this to implement your
own behavior.
@ret 1, If you handle the event; 0, If you don't handle the event;
@param x The X position of the mouse.
@param y The Y position of the mouse.
*/
virtual int onLeftButtonUp(int x, int y);
/**
Event is triggered when the right mouse button is pressed.
Override this to implement your own behavior.
*/
virtual int onRightButtonDown(int x, int y);
/**
Event is triggered when a key is pressed and the slider
has focus. Override this to implement your own behavior.
@ret 1, If you handle the event; 0, If you don't handle the event;
@param c The key that was pressed.
*/
virtual int onChar(unsigned int c);
/**
Event is triggered when the mouse enters the region
of the slider. Override this to implement your
own behavior.
*/
virtual void onEnterArea();
/**
Event is triggered when the mouse leaves the region
of the slider. Override this to implement your
own behavior.
*/
virtual void onLeaveArea();
/**
Event is triggered then the slider is about to be initialized.
Override this event to implement your own behavior.
By default this will render the slider according the it's current settings
and position of the thumb.
@ret 1, Success; 0, Failure;
*/
virtual int onInit();
/**
Constants for positioning of the thumb.
*/
enum {
START = 0,
END = 65535,
FULL = END
};
/**
Set the sliders position.
@param newpos The sliders new position.
@param wantcb !0, Generate a callback after the position has been set; 0, No callback;
*/
virtual void setPosition(int newpos, int wantcb=1);
/**
Get the sliders current position. The range is from
START (0) to END (65535).
@ret The sliders position (ranges from 0 to 65535).
*/
int getSliderPosition();
//void cancelSeek();
/**
Use a base texture when rendering the slider.
@see setBaseTexture()
@param useit 0, Do not use; 1, Use base texture;
*/
void setUseBaseTexture(int useit);
/**
Set the base texture of the slider.
@see setUseBaseTexture()
@see SkinBitmap
@param bmp The bitmap to use as a texture.
@param x The X position of the base texture.
@param y The Y position of the base texture.
*/
void setBaseTexture(SkinBitmap *bmp, int x, int y);
/**
Set the draw area to include the edge borders.
@param draw 0, Do not include the edges; 1, Include the edges;
*/
void setDrawOnBorders(int draw);
/**
Do not use the default background provided
by the current skin?
If you set this to 1, you MUST specify your bitmaps.
@param no 0, Use default background; 1, Do not use default;
*/
void setNoDefaultBackground(int no);
/**
Set the bitmaps to be used to render the slider.
These include bitmaps for the left, middle, right of
the slider. For the thumb, we have bitmaps for the
normal, hilited and pushed thumb.
The bitmaps are set using their xml id or "name".
The name should resemble something like this:
"studio.seekbar.left".
@see setLeftBmp()
@see setMiddleBmp()
@see setRightBmp()
@see setThumbBmp()
@see setThumbDownBmp()
@see setThumbHiliteBmp()
@param thumbbmp The normal thumb bitmap name.
@param thumbdownbmp The thumb down bitmap name.
@param thumbhighbmp The hilited thumb bitmap name.
@param leftbmp The left bitmap of the slider name.
@param middlebmp The middle bitmap of the slider name.
@param rightbmp The right bitmap of the slider name.
*/
void setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp);
/**
Set the left bitmap of the slider.
@param name The left bitmap name.
*/
void setLeftBmp(const wchar_t *name);
/**
Set the middle bitmap of the slider.
@param name The middle bitmap name.
*/
void setMiddleBmp(const wchar_t *name);
/**
Set the right bitmap of the slider.
@param name The right bitmap name.
*/
void setRightBmp(const wchar_t *name);
/**
Set the normal thumb bitmap of the slider.
@param name The normal thumb bitmap name.
*/
void setThumbBmp(const wchar_t *name);
/**
Set the thumb down bitmap of the slider.
@param name The thumb down bitmap name.
*/
void setThumbDownBmp(const wchar_t *name);
/**
Set the hilited thumb bitmap of the slider.
@param name The hilited thumb bitmap name.
*/
void setThumbHiliteBmp(const wchar_t *name);
/**
Get the height of the slider in pixels.
@ret The height of the slider (in pixels).
*/
virtual int getHeight();
/**
Get the width of the slider in pixels.
@ret The width of the slider (in pixels).
*/
virtual int getWidth();
/**
Get the left bitmap of the slider.
@see SkinBitmap
@ret The left SkinBitmap.
*/
SkinBitmap *getLeftBitmap();
/**
Get the right bitmap of the slider.
@see SkinBitmap
@ret The right SkinBitmap.
*/
SkinBitmap *getRightBitmap();
/**
Get the middle bitmap of the slider.
@see SkinBitmap
@ret The middle SkinBitmap.
*/
SkinBitmap *getMiddleBitmap();
/**
Get the thumb bitmap of the slider.
@see SkinBitmap
@ret The thumb SkinBitmap.
*/
SkinBitmap *getThumbBitmap();
/**
Get the thumb down bitmap of the slider.
@see SkinBitmap
@ret The thumb down SkinBitmap.
*/
SkinBitmap *getThumbDownBitmap();
/**
Get the thumb hilite bitmap of the slider.
@see SkinBitmap
@ret The thumb hilite SkinBitmap.
*/
SkinBitmap *getThumbHiliteBitmap();
/**
Set the sliders enable state.
@param en 1, Enabled; 0, Disabled;
*/
virtual void setEnable(int en);
/**
Get the sliders enable state.
@ret 1, Enabled; 0, Disabled;
*/
virtual int getEnable(void);
/**
Set the orientation of the slider
(horizontal or vertical).
@param o 0, Horizontal; 1, Vertical;
*/
virtual void setOrientation(int o);
/**
This will set a "jump-to" position (like "center" for a balance slider).
The parameter is in thumb coordinates (0 to 65535).
@param h The jump-to position (ranges from 0 to 65535, or START to END).
*/
virtual void setHotPosition(int h);
virtual int getHotPosRange() { return hotposrange; }
virtual void setHotPosRange(int range) { hotposrange = range; }
/**
Set the thumb center flag. If on, this flag will
cause the thumb of the slider to be centered
automatically.
@param c 1, Centered; 0, No centering;
*/
virtual void setThumbCentered(int c);
virtual void setThumbStretched(int c);
/**
Set the thumb offset (from the left hand side).
This offset will be added to the zero position of the thumb.
Note, if you're using centering also, this will cause the slider
thumb to be passed the middle of the slider.
@param o The offset of the thumb (in pixels).
*/
virtual void setThumbOffset(int o);
/**
Set the minimum and maximum limit for the slider.
@param minlimit The minimum value.
@param maxlimit The maximum value.
*/
virtual void setLimits(int minlimit, int maxlimit);
virtual int getMaxLimit() { return maxlimit; }
virtual int getMinLimit() { return minlimit; }
virtual int getRange() { return maxlimit-minlimit; }
virtual int onKeyDown(int vkcode);
virtual void onCancelCapture();
protected:
/**
Abort the current seek and end capture.
*/
void abort();
// override this to get position change notification
/**
Event is triggered when the mouse is moving the thumb
is being moved. Override this to implment your own behavior.
@ret The thumb's position (ranges from 0 to 65535 or START to END).
*/
virtual int onSetPosition(); // called constantly as mouse moves
/**
Event is triggered when the thumb is released and the final position
is about to be set.
@ret The thumb's position (ranges from 0 to 65535 or START to END).
*/
virtual int onSetFinalPosition(); // called once after move done
/**
Get the seeking status.
@ret 1, User is seeking; 0, User is not seeking;
*/
int getSeekStatus(); // returns 1 if user is sliding tab
int vertical; // set to 1 for up-n-down instead
/**
Get the width of the thumb bitmap, in pixels.
@ret The thumb's width (in pixels).
*/
int thumbWidth();
/**
Get the height of the thumb bitmap, in pixels.
@ret The thumb's width (in pixels).
*/
int thumbHeight();
// keyboard
void move_left(int bigstep);
void move_right(int bigstep);
void move_start();
void move_end();
int minlimit, maxlimit, length;
private:
int seeking;
int enabled;
int hilite;
int pos;
int oldpos;
int thumbwidth;
int captured;
int xShift, yShift;
SkinBitmap *base_texture;
int use_base_texture;
int no_default_background;
int drawOnBorders;
int hotPosition;
int origPos;
int thumbCentered, thumbOffset, thumbStretched;
int hotposrange;
AutoSkinBitmap left, middle, right;
AutoSkinBitmap thumb, thumbdown, thumbhilite;
};
#endif
+242
View File
@@ -0,0 +1,242 @@
#include <precomp.h>
#include "status.h"
#include <tataki/color/skinclr.h>
#include <tataki/canvas/canvas.h>
#include <api/wnd/wndclass/buttbar.h>
#include <api/wnd/wndclass/buttwnd.h>
#include <api/wndmgr/appcmds.h>
#include <bfc/parse/paramparser.h>
#include <api/script/objects/c_script/c_text.h>
#define STATUS_TIMER_DECAY 1
#define COMPLETED_WIDTH 96
static SkinColor textcolor(L"wasabi.statusbar.text");
class CmdButton : public ButtonWnd
{
public:
CmdButton(const wchar_t *name, AppCmds *_cmd, int _id) : ButtonWnd(name), cmd(_cmd), id(_id) {}
virtual void onLeftPush(int x, int y) {
cmd->appcmds_onCommand(id, &windowRect(), AppCmds::LEFT_CLICK);
}
virtual void onRightPush(int x, int y) {
cmd->appcmds_onCommand(id, &windowRect(), AppCmds::RIGHT_CLICK);
}
virtual int wantAutoContextMenu() { return 0; }
AppCmds *cmd;
int id;
};
StatusBar::StatusBar() {
overtimer = 0;
max = 0;
completed = 0;
progress_width = 0;
bg.setContent(L"wasabi.statusbar");
bbleft = bbright = NULL;
}
StatusBar::~StatusBar()
{
killTimer(STATUS_TIMER_DECAY);
delete bbleft;
delete bbright;
}
int StatusBar::onInit() {
STATUSBAR_PARENT::onInit();
bg.init(this);
#ifdef WASABI_COMPILE_WNDMGR
getGuiObject()->guiobject_registerStatusCB(this); // watched
#endif
regenerate();
return 1;
}
void StatusBar::timerCallback(int id) {
switch (id) {
case STATUS_TIMER_DECAY: {
killTimer(STATUS_TIMER_DECAY);
onSetStatusText(status_text, FALSE); // revert to main text
}
break;
default:
STATUSBAR_PARENT::timerCallback(id);
break;
}
}
void StatusBar::pushCompleted(int _max) {
max = MAX(_max, 0);
completed = 0;
GuiObject *outer = bg.findObject(L"wasabi.statusbar.progress.outline");
outer->guiobject_setXmlParam(L"visible", L"0");
ASSERT(outer != NULL);
ifc_window *outerw = outer->guiobject_getRootWnd();
RECT cr;
outerw->getClientRect(&cr);
progress_width = cr.right - cr.left;
outerw->setVisible(TRUE);//CUT
outer->guiobject_setTargetA(255);
outer->guiobject_setTargetSpeed(0.1f);
outer->guiobject_gotoTarget();
GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
inner->guiobject_setTargetA(255);
inner->guiobject_setTargetSpeed(1.0f);
inner->guiobject_gotoTarget();
inner->guiobject_setXmlParam(L"visible", L"0");
incCompleted(0);
}
void StatusBar::incCompleted(int add) {
setCompleted(completed + add);
}
void StatusBar::setCompleted(int _completed) {
completed = _completed;
GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
ASSERT(inner != NULL);
if (!inner->guiobject_getRootWnd()->isVisible(1)) {
inner->guiobject_setXmlParam(L"visible", L"1");
inner->guiobject_setTargetA(255);
inner->guiobject_setTargetSpeed(0.75);
inner->guiobject_gotoTarget();
}
int pos = (int)(((float)completed / (float)max)*(float)progress_width);
inner->guiobject_setXmlParam(L"w", StringPrintfW(L"%d", pos));
}
void StatusBar::popCompleted() {
completed = 0;
max = 0;
GuiObject *inner = bg.findObject(L"wasabi.statusbar.progress.inside");
inner->guiobject_setXmlParam(L"w", L"0");
inner->guiobject_setTargetA(0);
inner->guiobject_setTargetSpeed(0.75);
inner->guiobject_gotoTarget();
//CUT later
inner->guiobject_setXmlParam(L"visible", L"0");
GuiObject *outer = bg.findObject(L"wasabi.statusbar.progress.outline");
outer->guiobject_setXmlParam(L"visible", L"0");
}
int StatusBar::onResize() {
STATUSBAR_PARENT::onResize();
RECT cr = clientRect();
bbleft->resize(cr.left, cr.top, bbleft->getWidth(), cr.bottom - cr.top);
bbright->resize(cr.right-bbright->getWidth(), cr.top, bbright->getWidth(), cr.bottom - cr.top);
cr.left += bbleft->getWidth();
cr.right -= bbright->getWidth();
bg.resizeToRect(&cr); // put bg group in place
invalidate();
return 1;
}
void StatusBar::onSetStatusText(const wchar_t *text, int overlay)
{
killTimer(STATUS_TIMER_DECAY);
if (!overlay)
status_text = text;
else setTimer(STATUS_TIMER_DECAY, 4000);
ScriptObject *tx = bg.findScriptObject(L"wasabi.statusbar.text");
if (tx == NULL) return;
C_Text(tx).setText(text ? text : L"");
}
void StatusBar::onAddAppCmds(AppCmds *commands) {
if (appcmds.haveItem(commands)) appcmds.removeItem(commands);
appcmds.addItem(commands);
regenerate();
}
void StatusBar::onRemoveAppCmds(AppCmds *commands) {
if (appcmds.haveItem(commands)) {
appcmds.removeItem(commands);
regenerate();
}
}
void StatusBar::regenerate() {
if (!isInited()) return;
delete bbleft; bbleft = new ButtBar;
delete bbright; bbright = new ButtBar;
bbleft->init(this);
bbright->init(this);
ParamParser exclude(exclude_list, L";");
ParamParser showonly(include_only, L";");
foreach(appcmds)
int n = appcmds.getfor()->appcmds_getNumCmds();
for (int i = 0; i < n; i++) {
int side, id;
const wchar_t *name = appcmds.getfor()->appcmds_enumCmd(i, &side, &id);
if (name == NULL) break;
if (exclude.hasString(name)) continue; // exclusion list
if (showonly.getNumItems()) {
if (!showonly.hasString(name)) continue; // include-only list
}
CmdButton *cb = new CmdButton(name, appcmds.getfor(), id);
// cb->setXmlParam("wantfocus", "1");
if (side == AppCmds::SIDE_LEFT) bbleft->addChild(cb);
else bbright->addChild(cb);
}
endfor
if (isPostOnInit())
onResize();
}
void StatusBar::fakeButtonPush(const wchar_t *name) {
if (!fakeButtonPush(bbleft, name))
fakeButtonPush(bbright, name);
}
int StatusBar::fakeButtonPush(ButtBar *bb, const wchar_t *name)
{
for (int i = 0; i < bb->getNumChildren(); i++) {
ButtonWnd *cmdb = bb->enumChild(i);
if (!WCSICMP(cmdb->getName(), name)) {
int x, y;
Wasabi::Std::getMousePos(&x, &y);
cmdb->screenToClient(&x, &y);
cmdb->onLeftPush(x, y);
return 1;
}
}
return 0;
}
void StatusBar::setExclude(const wchar_t *val) {
exclude_list = val;
regenerate();
}
void StatusBar::setIncludeOnly(const wchar_t *val) {
include_only = val;
regenerate();
}
+178
View File
@@ -0,0 +1,178 @@
#ifndef _STATUS_H
#define _STATUS_H
#include <api/wnd/wndclass/guiobjwnd.h>
#include <bfc/string/StringW.h>
#include <api/wndmgr/guistatuscb.h>
#include <bfc/depend.h>
class ButtBar;
class AppCmds;
#define STATUSBAR_PARENT GuiObjectWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class StatusBar : public STATUSBAR_PARENT, public GuiStatusCallbackI {
public:
/**
Method
@see
@ret
@param
*/
StatusBar();
/**
Method
@see
@ret
@param
*/
virtual ~StatusBar();
/**
Method
@see
@ret
@param
*/
virtual int onInit();
// completeness indicator
/**
Method
@see
@ret
@param
*/
virtual void pushCompleted(int max);
/**
Method
@see
@ret
@param
*/
virtual void incCompleted(int add);
/**
Method
@see
@ret
@param
*/
virtual void setCompleted(int pos);
/**
Method
@see
@ret
@param
*/
virtual void popCompleted();
/**
Method
@see
@ret
@param
*/
virtual void timerCallback(int id);
/**
Method
@see
@ret
@param
*/
virtual int onResize();
virtual api_dependent *status_getDependencyPtr() { return this; }
/**
Method
@see
@ret
@param
*/
virtual void onSetStatusText(const wchar_t *text, int overlay);
/**
Method
@see
@ret
@param
*/
virtual void onAddAppCmds(AppCmds *commands);
/**
Method
@see
@ret
@param
*/
virtual void onRemoveAppCmds(AppCmds *commands);
/**
Method
@see
@ret
@param
*/
void fakeButtonPush(const wchar_t *name);
protected:
int fakeButtonPush(ButtBar *bb, const wchar_t *name);
void setExclude(const wchar_t *val);
void setIncludeOnly(const wchar_t *val);
StringW exclude_list, include_only;
protected:
void regenerate();
private:
StringW contentgroupname;
StringW status_text;
int overtimer;
// completeness
int max;
int completed;
int progress_width;
GuiObjectWnd bg;
ButtBar *bbleft, *bbright;
PtrList<AppCmds> appcmds;
};
#endif
@@ -0,0 +1,53 @@
#include <precomp.h>
#include "svcwndhold.h"
#include <bfc/common.h>
#include <api/service/svcs/svc_wndcreate.h>
#include <api/wnd/wndclass/blankwnd.h>
ServiceWndHolder::ServiceWndHolder(ifc_window *_child, svc_windowCreate *_svc) :
child(NULL), svc(NULL)
{
setChild(_child, _svc);
}
ServiceWndHolder::~ServiceWndHolder()
{
if (svc != NULL)
{
svc->destroyWindow(child);
if (!svc->refcount())
WASABI_API_SVC->service_release(svc);
} else {
delete static_cast<BaseWnd*>(child);
}
}
int ServiceWndHolder::setChild(ifc_window *_child, svc_windowCreate *_svc)
{
if (child == _child && svc == _svc) return 0;
if (child != NULL) {
if (svc != NULL) {
svc->destroyWindow(child);
if (!svc->refcount())
WASABI_API_SVC->service_release(svc);
svc = NULL;
} else {
delete static_cast<BaseWnd*>(child);
}
child = NULL;
}
child = _child;
svc = _svc;
return 1;
}
ifc_window *ServiceWndHolder::rootwndholder_getRootWnd() {
return child ? child : SERVICEWNDHOLDER_PARENT::rootwndholder_getRootWnd();
}
+51
View File
@@ -0,0 +1,51 @@
#ifndef _SVCWNDHOLD_H
#define _SVCWNDHOLD_H
#include <api/wnd/wndclass/rootwndholder.h>
#include <bfc/common.h>
class svc_windowCreate;
// for some reason if this derives from virtualwnd typesheet won't show it
#define SERVICEWNDHOLDER_PARENT RootWndHolder
/**
class ServiceWndHolder .
@short
@author Nullsoft
@ver 1.0
@see
*/
class ServiceWndHolder : public SERVICEWNDHOLDER_PARENT {
public:
/**
ServiceWndHolder constructor .
@param _child A pointer to the child we want to set.
@param _svc A pointer to the window creation service associated with the window we want to set as a child.
*/
ServiceWndHolder(ifc_window *child=NULL, svc_windowCreate *svc=NULL);
/**
ServiceWndHolder destructor
*/
virtual ~ServiceWndHolder();
/**
ServiceWndHolder method setChild .
@ret 1
@param _child A pointer to the child we want to set.
@param _svc A pointer to the window creation service associated with the window we want to set as a child.
*/
int setChild(ifc_window *child, svc_windowCreate *svc);
virtual ifc_window *rootwndholder_getRootWnd();
private:
ifc_window *child;
svc_windowCreate *svc;
};
#endif
+544
View File
@@ -0,0 +1,544 @@
#include "precomp.h"
#include "tabsheet.h"
#include "buttwnd.h"
#include "buttbar.h"
#include "tabsheetbar.h"
#include <bfc/wasabi_std.h>
#include <api/wnd/notifmsg.h>
#include <api/script/objects/c_script/c_text.h>
#include <api/script/objects/c_script/c_group.h>
#include <api/wnd/PaintCanvas.h>
TabSheet::TabSheet(int bbtype) {
leftscroll = rightscroll = NULL;
background = NULL;
tabrowmargin = 0;
active = NULL;
type = bbtype;
bb = NULL;
tsb = NULL;
content_margin_top = content_margin_right = content_margin_left = content_margin_bottom = 0;
contentwnd = NULL;
if (bbtype == TABSHEET_GROUPS) {
tsb = new TabSheetBar();
tsb->setParent(this);
} else { // schweitn rulz
bb = new ButtBar((bbtype == -1) ? ButtBar::NORMAL : bbtype);
bb->setParent(this);
if (bbtype == TABSHEET_NOTABS)
bb->setStartHidden(1);
}
}
TabSheet::~TabSheet() {
delete bb; // kills tabs and child wnds
delete tsb;
delete leftscroll;
delete rightscroll;
delete background;
delete contentwnd;
}
void TabSheet::setButtonType(int _type) {
type = _type;
if (contentwnd != NULL) {
if (type == ButtBar::STACK)
contentwnd->setContent(L"wasabi.tabsheet.content.noborder");
else if (type != TABSHEET_NOTABS)
contentwnd->setContent(L"wasabi.tabsheet.content");
else
contentwnd->setContent(NULL);
}
if (_type == TABSHEET_GROUPS && bb != NULL) {
PtrList<BaseWnd> l;
foreach(tabs)
l.addItem(tabs.getfor()->getBaseWnd());
tabs.getfor()->setNoDeleteLinked(1);
endfor;
delete bb; bb = NULL;
tabs.removeAll();
tsb = new TabSheetBar();
tsb->setParent(this);
if (isInited())
tsb->init(this);
foreach(l)
addChild(l.enumItem(foreach_index));
endfor;
} else if (_type != TABSHEET_GROUPS && tsb != NULL) {
PtrList<BaseWnd> l;
foreach(tabs)
l.addItem(tabs.getfor()->getBaseWnd());
tabs.getfor()->setNoDeleteLinked(1);
endfor;
delete tsb; tsb = NULL;
tabs.removeAll();
bb = new ButtBar((type == -1) ? ButtBar::NORMAL : type);
bb->setParent(this);
if (type == TABSHEET_NOTABS)
bb->setStartHidden(1);
if (isInited())
bb->init(this);
foreach(l)
addChild(l.enumItem(foreach_index));
endfor;
}
if (bb != NULL) bb->setResizeMode(type);
}
void TabSheet::killChildren() {
if (bb) {
delete bb; // kills tabs and child wnds
bb = new ButtBar((type == -1) ? ButtBar::NORMAL : type);
bb->setParent(this);
if (type == TABSHEET_NOTABS)
bb->setStartHidden(1);
bb->init(this);
}
if (tsb) {
delete tsb; // kills tabs and child wnds
tsb = new TabSheetBar;
tsb->setParent(this);
tsb->init(this);
}
// mig: if you don't do this, you crash changing tabsheets at runtime.
tabs.removeAll();
active = NULL;
}
int TabSheet::onInit() {
TABSHEET_PARENT::onInit();
contentwnd = new GuiObjectWnd;
if (type == ButtBar::STACK)
contentwnd->setContent(L"wasabi.tabsheet.content.noborder");
else if (type != TABSHEET_NOTABS)
contentwnd->setContent(L"wasabi.tabsheet.content");
else
contentwnd->setContent(NULL);
contentwnd->setParent(this);
contentwnd->init(this);
rootwndholder_setRootWnd(contentwnd);
if (leftscroll != NULL) {
leftscroll->init(this);
leftscroll->setParent(this);
}
if (rightscroll != NULL) {
rightscroll->init(this);
rightscroll->setParent(this);
}
// init the windows
foreach(tabs)
if (foreach_index != 0) tabs.getfor()->getBaseWnd()->setStartHidden(TRUE);
tabs.getfor()->getBaseWnd()->init(this);
endfor
if (bb) {
bb->setParent(this);
if (type == TABSHEET_NOTABS)
bb->setStartHidden(1);
bb->init(this); // inits the tabs
}
if (tsb) {
tsb->setParent(this);
tsb->init(this); // inits the tabs
}
if (tabs.getNumItems() > 0) {
active = tabs[0]->getBaseWnd();
//tabs[0]->setHilite(TRUE); // FG: FIX!
}
if (isPostOnInit())
onResize();
return 1;
}
void TabSheet::getClientRect(RECT *r) {
TABSHEET_PARENT::getClientRect(r);
if (bb) {
if (type != TABSHEET_NOTABS)
r->top += bb->getHeight();
} else
r->top += tsb->getHeight();
r->left += content_margin_left;
r->top += content_margin_top;
r->right -= content_margin_right;
r->bottom -= content_margin_bottom;
}
#ifdef WASABI_COMPILE_IMGLDR
void TabSheet::setBackgroundBmp(const wchar_t *name)
{
if (background) delete background;
background = NULL;
if (name && *name)
background = new SkinBitmap(name);
}
#endif
SkinBitmap *TabSheet::getBackgroundBitmap() {
return background;
}
int TabSheet::onPaint(Canvas *canvas) {
PaintBltCanvas paintcanvas;
if (canvas == NULL) {
if (!paintcanvas.beginPaintNC(this)) return 0;
canvas = &paintcanvas;
}
TABSHEET_PARENT::onPaint(canvas);
RECT r;
TABSHEET_PARENT::getClientRect(&r);
if (bb) {
if (type != TABSHEET_NOTABS)
r.bottom = r.top + bb->getHeight();
}
else if (tsb)
r.bottom = r.top + tsb->getHeight();
RECT br = r;
if (leftscroll) br.left += leftscroll->getWidth();
if (rightscroll) br.right -= rightscroll->getWidth();
if (br.right <= br.left) return 1;
if (background != NULL) {
#if 0
int i, x = tilex;
for (i = 0; ; i++) {
tile->stretch(canvas, x, 0, tile->getWidth(), tabrowheight);
x += tile->getWidth();
if (x >= r.right) break;
}
#else
#if 0
if (background->getAlpha()) api->skin_renderBaseTexture(canvas, br);
background->stretchToRectAlpha(canvas, &br);
#else
background->stretchToRect(canvas, &br);
#endif
#endif
} else {
#if 0
r.top = 0;
r.bottom = tabrowheight;
r.left = tilex;
r.right = tilex + tilew;
canvas->fillRect(&r, RGB(64, 64, 64));
#else
// api->skin_renderBaseTexture(canvas, r);
#endif
}
return 1;
}
void TabSheet::setTabRowMargin(int newmargin) {
ASSERT(newmargin >= 0);
tabrowmargin = newmargin;
onResize();
}
int TabSheet::addChild(BaseWnd *newchild, const wchar_t *tip) {
ASSERT(newchild != NULL);
int first=0;
if (tabs.getNumItems() == 0) first = 1;
if (isInited() && !newchild->isInited()) {
if (!first) newchild->setStartHidden(TRUE);
ifc_window *holder = this;
if (contentwnd != NULL) {
if (contentwnd->getContentRootWnd() != NULL) {
GuiObject *o = contentwnd->getContent()->guiobject_findObject(L"content");
if (o != NULL)
holder = o->guiobject_getRootWnd();
}
}
newchild->setParent(holder);
newchild->init(holder);
}
if (bb)
{
TabButton *tab = new TabButton(newchild, this, tip);
tabs.addItem(tab);
bb->addChild(tab);
}
else if (tsb)
{
GroupTabButton *tab = new GroupTabButton(newchild, this, tip);
tabs.addItem(tab);
tsb->addChild(tab);
}
if (isInited()) {
if (first) {
activateChild(newchild);
}
}
if (isPostOnInit()) onResize();
return tabs.getNumItems()-1;
}
void TabSheet::activateChild(BaseWnd *newactive) {
BaseWnd *prevactive = active;
if (newactive == NULL) newactive = active;
if (prevactive == newactive) return; // not a switch
#if 0
RECT r = clientRect();
int w = r.right - r.left + 1;
int h = r.bottom - r.top + 1;
#endif
int prevpos=-1, nextpos=-1;
for (int i = 0; i < tabs.getNumItems(); i++) {
if (prevactive == tabs[i]->getBaseWnd()) prevpos = i;
if (newactive == tabs[i]->getBaseWnd()) nextpos = i;
}
if (prevpos != -1) tabs[prevpos]->btn_setHilite(FALSE);
if (nextpos < tabs.getNumItems()) tabs[nextpos]->btn_setHilite(TRUE);
#if 0
// reveal tha new winder
if (newactive!= NULL) newactive->setVisible(TRUE);
enable(FALSE);
if (prevactive!= NULL) prevactive->enable(FALSE);
if (newactive!= NULL) newactive->enable(FALSE);
#define STEPS 6
// find which window is now active
for (int c = 0; c < STEPS; c++) {
int x;
if (prevpos > nextpos) x = (w * c) / STEPS; // right to left
else x = (w * (STEPS - c)) / STEPS; // left to right
int y = r.top;
if (prevpos > nextpos) {
if (newactive!= NULL) newactive->move(x - w, y);
if (prevactive!= NULL) prevactive->move(x, y);
} else {
if (newactive!= NULL) newactive->move(x, y);
if (prevactive!= NULL) prevactive->move(x - w, y);
}
if (newactive!= NULL) newactive->repaint();
if (prevactive!= NULL) prevactive->repaint();
Sleep(15);
}
#endif
if (newactive!= NULL) newactive->setVisible(TRUE);
if (prevactive!= NULL) prevactive->setVisible(FALSE);
#if 0
enable(TRUE);
if (prevactive!= NULL) prevactive->enable(TRUE);
if (newactive!= NULL) newactive->enable(TRUE);
#endif
if (bb && newactive)
bb->setGroupLabel(newactive->getName());
active = newactive;
onSetPage(nextpos);
}
int TabSheet::onResize() {
TABSHEET_PARENT::onResize();
if (!isInited()) return 1;
RECT r = clientRect();
// put buttbar at the top
if (bb) bb->resize(r.left, r.top-bb->getHeight(), r.right-r.left, bb->getHeight()+1);
if (tsb) tsb->resize(r.left, r.top-tsb->getHeight(), r.right-r.left, tsb->getHeight()+1);
// resize content group if it's there
if (contentwnd) {
contentwnd->resize(&r);
// since its holder is not resizing its content, we need to do it ourselves
foreach(tabs)
BaseWnd *c = tabs.getfor()->getBaseWnd();
if (c->getParent() != NULL && c->getParent() != this && c->getParent()->getParent() == contentwnd->getContentRootWnd()) {
RECT r;
c->getParent()->getClientRect(&r);
c->resize(&r);
} else {
// if we're holding it directly, resize it to our rect
c->resize(&r);
}
endfor
}
invalidate();
if (leftscroll)
leftscroll->invalidate();
if (rightscroll)
rightscroll->invalidate();
return 1;
}
BaseWnd *TabSheet::enumChild(int child) {
TabButtonBase *tb = tabs[child];
if (tb == NULL) return NULL;
return tb->getBaseWnd();
}
int TabSheet::getNumChild() {
return tabs.getNumItems();
}
void TabSheet::setCurPage(int page) {
BaseWnd *e = enumChild(page);
if (e != NULL) activateChild(e);
}
TabButtonBase *TabSheet::enumButton(int i) {
if (i < tabs.getNumItems())
return tabs[i];
else
return NULL;
}
int TabSheet::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
if (msg == ChildNotify::NAMECHANGED)
{
foreach(tabs)
ifc_window *w = tabs.getfor()->getBaseWnd();
if (w == child || w == child->getParent()) {
const wchar_t *name = child->getRootWndName();
tabs.getfor()->btn_setText(name && *name ? name : L"[?]");
}
endfor;
}
if (msg == ChildNotify::GROUPRELOAD && child == contentwnd) {
foreach(tabs)
ifc_window *holder = this;
if (contentwnd->getContentRootWnd() != NULL) {
GuiObject *o = contentwnd->getContent()->guiobject_findObject(L"content");
if (o != NULL)
holder = o->guiobject_getRootWnd();
}
tabs.getfor()->getBaseWnd()->reparent(holder);
endfor;
}
return TABSHEET_PARENT::childNotify(child, msg, param1, param2);
}
void TabSheet::setContentMarginLeft(int cm) {
content_margin_left = cm;
if (isInited())
onResize();
}
void TabSheet::setContentMarginTop(int cm) {
content_margin_top = cm;
if (isInited())
onResize();
}
void TabSheet::setContentMarginRight(int cm) {
content_margin_right = cm;
if (isInited())
onResize();
}
void TabSheet::setContentMarginBottom(int cm) {
content_margin_bottom = cm;
if (isInited())
onResize();
}
int TabSheet::onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source) {
if (!WCSICMP(action, L"Tabsheet:NextPage")) { nextPage(); return 1; }
if (!WCSICMP(action, L"Tabsheet:PreviousPage")) { previousPage(); return 1; }
return TABSHEET_PARENT::onAction(action, param, x, y, p1, p2, data, datalen, source);
}
// TabButton
TabButtonBase::TabButtonBase(BaseWnd *linkwnd, TabSheet *par, const wchar_t *tip)
: linked(linkwnd), parent(par) {
nodeletelinked = 0;
ASSERT(linked != NULL);
}
TabButtonBase::~TabButtonBase() {
if (!nodeletelinked) delete linked;
}
int TabButton::onInit()
{
TABBUTTON_PARENT::onInit();
setButtonText(linked->getNameSafe(L"[?]"));
return 1;
}
void TabButton::onLeftPush(int x, int y) {
ASSERT(parent != NULL);
ASSERT(linked != NULL);
parent->activateChild(linked);
}
void TabButton::btn_setHilite(int tf) {
setHilite(tf);
}
void TabButton::btn_setText(const wchar_t *text)
{
setButtonText(text);
}
// GroupTabButton
void GroupTabButton::grouptoggle_onLeftPush() {
GROUPTABBUTTON_PARENT::grouptoggle_onLeftPush();
ASSERT(parent != NULL);
ASSERT(linked != NULL);
parent->activateChild(linked);
}
void GroupTabButton::btn_setHilite(int tf) {
setStatus(tf ? STATUS_ON : STATUS_OFF);
}
void GroupTabButton::btn_setText(const wchar_t *text)
{
for (int i=0;i<getNumGroups();i++) {
GuiObject *grp = enumGroups(i)->getContent();
if (grp != NULL) {
GuiObject *o = grp->guiobject_findObject(L"text");
if (o != NULL) {
C_Text txt(o->guiobject_getScriptObject());
txt.setText(text);
}
}
}
}
int GroupTabButton::onInit() {
int rt = GROUPTABBUTTON_PARENT::onInit();
btn_setText(linked->getNameSafe(L"[?]"));
return rt;
}
+268
View File
@@ -0,0 +1,268 @@
#ifndef _TABSHEET_H
#define _TABSHEET_H
#include <api/skin/widgets/grouptgbutton.h>
#include <api/wnd/wndclass/buttwnd.h>
#include <bfc/common.h>
#include <api/wnd/wndclass/guiobjwnd.h>
#include <bfc/ptrlist.h>
class ButtonWnd;
class SkinBitmap;
class TabButtonBase;
class ButtBar;
class TabSheetBar;
#define TABSHEET_GROUPS -2
#define TABSHEET_NOTABS -3
#define TABSHEET_PARENT GuiObjectWnd
/**
class TabSheet
@short A TabSheet Control.
@author Nullsoft
@ver 1.0
@see
@cat SDK
*/
class TabSheet : public TABSHEET_PARENT
{
public:
/**
TabSheet constructor
@see ~TabSheet()
@param bbtype The type of button bar to use in the tabsheet.
*/
TabSheet(int bbtype=-1);
/**
TabSheet destructor
@see TabSheet()
*/
virtual ~TabSheet();
/**
TabSheet method onInit
@ret 1
*/
virtual int onInit();
/**
TabSheet method getClientRect
@param r A pointer to the RECT that will be filled.
*/
virtual void getClientRect(RECT *);
/**
TabSheet method onPaint
@ret 1
@param canvas The canvas upon which we'll paint ourself.
*/
virtual int onPaint(Canvas *canvas);
/**
TabSheet method onResize
@ret 1
*/
virtual int onResize();
/**
TabSheet method setButtonType .
@param type The button type.
*/
void setButtonType(int type);
/**
TabSheet method setTabRowMargin
@assert newmargin is non-negative
@param newmargin The new margin width in pixels.
*/
void setTabRowMargin(int pixels);
/**
TabSheet method addChild
@ret One less than the number of tabs
@param newchild A pointer to the new child window to add.
@param tip The tooltip for the button associated with this child.
*/
int addChild(BaseWnd *newchild, const wchar_t *tooltip=NULL);
/**
TabSheet method activateChild
@see addChild()
@see killChildren()
@ret None
@param newactive A pointer to the child window to render active.
*/
virtual void activateChild(BaseWnd *activechild);
/**
TabSheet method killChildren .
*/
virtual void killChildren();
/**
TabSheet method childNotify .
@ret Returns 1 when complete.
@param child The child that's being notified.
@param msg The message.
@param param1 Custom parameter 1.
@param param2 Custom parameter 2.
*/
virtual int childNotify(ifc_window *child, int msg,
intptr_t param1=0, intptr_t param2=0);
void setContentMarginLeft(int cm);
void setContentMarginTop(int cm);
void setContentMarginRight(int cm);
void setContentMarginBottom(int cm);
/**
TabSheet method enumChild
@ret The base window of the specified tab button, or NULL if there is none.
*/
BaseWnd *enumChild(int child);
/**
TabSheet method getNumChild
@ret The number of tabs
*/
int getNumChild();
BaseWnd *getActiveChild() { return active; }
virtual void onSetPage(int n) { lastpage = n; }
int getCurPage() { return lastpage; }
void setCurPage(int page);
int getNumPages() { return tabs.getNumItems(); }
void nextPage() { int n = getCurPage()+1; if (n >= getNumPages()) n = 0; setCurPage(n); }
void previousPage() { int n = getCurPage()-1; if (n < 0) n = getNumPages()-1; setCurPage(n); }
int onAction(const wchar_t *action, const wchar_t *param, int x, int y, intptr_t p1, intptr_t p2, void *data, size_t datalen, ifc_window *source);
protected:
/** TabSheet method enumButton
@ret The specified tab, or NULL if there is none. */
TabButtonBase *enumButton(int button);
public:
/**
TabSheet method setBackgroundBmp
@param name The name of the bitmap to use.
*/
#ifdef WASABI_COMPILE_IMGLDR
void setBackgroundBmp(const wchar_t *name); //FG
#endif
SkinBitmap *getBackgroundBitmap(); //FG
protected:
// you can set these in your constructor, they will be deleted for you
ButtonWnd *leftscroll, *rightscroll;
SkinBitmap *background;
private:
int tabrowheight, tabrowwidth, tabrowmargin;
PtrList<TabButtonBase> tabs;
ButtBar *bb;
TabSheetBar *tsb;
GuiObjectWnd *contentwnd;
int tilex, tilew;
BaseWnd *active;
int type;
int content_margin_left, content_margin_top, content_margin_right, content_margin_bottom;
int lastpage;
};
class TabButtonBase
{
public:
TabButtonBase(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL);
virtual ~TabButtonBase();
BaseWnd *getBaseWnd() const { return linked; }
void setNoDeleteLinked(int i) { nodeletelinked = i; }
virtual void btn_setHilite(int tf)=0;
virtual void btn_setText(const wchar_t *txt)=0;
protected:
BaseWnd *linked;
TabSheet *parent;
int nodeletelinked;
};
#define TABBUTTON_PARENT ButtonWnd
/**
Class TabButton
@short
@author Nullsoft
@ver 1.0
@see TabButtonBase
@cat SDK
*/
class TabButton : public TABBUTTON_PARENT, public TabButtonBase {
public:
/**
TabButton constructor
@assert The BaseWnd passed to this method must previously be linked.
@param linkwnd The window to associate with this button.
@param par A pointer to the parent tabsheet.
@param tip The tooltip for the window associated with this button.
*/
TabButton(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL) : TabButtonBase(linkWnd, par, tip)
{
if (tip != NULL)
setTip(tip);
}
/**
TabButton method onInit
@ret 1
*/
virtual int onInit();
/**
TabButton method onLeftPush .
@assert parent and linked both exist.
@param x The X position, of the mouse pointer, in the client screen.
@param y The Y position, of the mouse pointer, in the client screen.
*/
virtual void onLeftPush(int x, int y);
virtual void btn_setHilite(int tf);
virtual void btn_setText(const wchar_t *text);
};
#define GROUPTABBUTTON_PARENT GroupToggleButton
class GroupTabButton : public GROUPTABBUTTON_PARENT, public TabButtonBase {
public:
GroupTabButton(BaseWnd *linkWnd, TabSheet *par, const wchar_t *tip=NULL) : TabButtonBase(linkWnd, par, tip)
{
setGroups(L"wasabi.tabsheet.button.selected.group", L"wasabi.tabsheet.button.unselected.group");
}
virtual int wantFullClick() { return 0; }
virtual int wantAutoToggle() { return 0; }
virtual int onInit();
virtual void grouptoggle_onLeftPush();
virtual void btn_setHilite(int tf);
virtual void btn_setText(const wchar_t *text);
};
#endif
+130
View File
@@ -0,0 +1,130 @@
#include "precomp.h"
#include "tabsheetbar.h"
#include "tabsheet.h"
#include "../notifmsg.h"
TabSheetBar::TabSheetBar() {
margin = 0;
spacing = -4;
maxheightsofar = 0;
bottombar.setParent(this);
}
TabSheetBar::~TabSheetBar()
{
btns.deleteAll();
}
int TabSheetBar::onInit() {
int rt = TABSHEETBAR_PARENT::onInit();
bottombar.setContent(L"wasabi.tabsheet.nobutton.group");
bottombar.init(this);
foreach(btns)
GroupTabButton *gtb = btns.getfor();
gtb->setParent(this);
if (!gtb->isInited()) {
gtb->init(this);
}
if (foreach_index == 0)
gtb->setStatus(STATUS_ON);
else
gtb->setStatus(STATUS_OFF);
int h = gtb->getPreferences(SUGGESTED_H);
if (h == AUTOWH) h = maxheightsofar;
maxheightsofar = MAX(maxheightsofar, h);
endfor;
return rt;
}
void TabSheetBar::addChild(GroupTabButton *child) {
ASSERT(!btns.haveItem(child));
btns.addItem(child);
if (isInited()) {
child->setParent(this);
if (!child->isInited()) {
child->init(this);
}
int h = child->getPreferences(SUGGESTED_H);
if (h == AUTOWH) h = maxheightsofar;
maxheightsofar = MAX(maxheightsofar, h);
onResize();
}
if (btns.getNumItems() == 1)
child->setStatus(STATUS_ON);
else
child->setStatus(STATUS_OFF);
}
int TabSheetBar::getHeight() {
return maxheightsofar;
}
int TabSheetBar::onResize() {
int rt = TABSHEETBAR_PARENT::onResize();
GroupTabButton *selected=NULL;
foreach(btns)
if (btns.getfor()->getStatus() == STATUS_ON) {
selected = btns.getfor();
break;
}
endfor;
if (selected == NULL) selected = btns.getFirst();
RECT r;
getClientRect(&r);
int x = margin;
foreach(btns)
GroupTabButton *gtb = btns.getfor();
int w = gtb->getPreferences(SUGGESTED_W);
if (w == AUTOWH) w = 66;
RECT dr;
dr.left = r.left + x;
dr.top = r.top;
dr.right = dr.left + w;
dr.bottom = dr.top + getHeight();
gtb->resize(&dr);
x += w + spacing;
endfor;
x -= spacing;
RECT dr;
dr.left = r.left + x;
dr.top = r.top;
dr.right = r.right;
dr.bottom = r.top + getHeight();
bottombar.resize(&dr);
if (selected != NULL)
selected->bringToFront();
return rt;
}
int TabSheetBar::childNotify(ifc_window *child, int msg, intptr_t param1/* =0 */, intptr_t param2/* =0 */) {
if (msg == ChildNotify::GROUPCLICKTGBUTTON_CLICKED && btns.haveItem(static_cast<GroupTabButton *>(child))) {
GroupToggleButton *but = NULL;
foreach(btns)
if (btns.getfor() != child)
btns.getfor()->setStatus(STATUS_OFF);
else
but = btns.getfor();
endfor;
if (but != NULL)
but->setStatus(STATUS_ON);
else
(static_cast<GroupToggleButton *>(child))->setStatus(STATUS_ON);
onResize();
}
if (msg == ChildNotify::AUTOWHCHANGED && btns.haveItem(static_cast<GroupTabButton *>(child)) && isPostOnInit())
onResize();
return TABSHEETBAR_PARENT::childNotify(child, msg, param1, param2);
}
+39
View File
@@ -0,0 +1,39 @@
#ifndef __TABSHEETBAR_H
#define __TABSHEETBAR_H
#include <api/wnd/wndclass/guiobjwnd.h>
class GroupTabButton;
#define TABSHEETBAR_PARENT GuiObjectWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class TabSheetBar : public TABSHEETBAR_PARENT
{
public:
TabSheetBar();
virtual ~TabSheetBar();
virtual int onInit();
virtual int onResize();
virtual void addChild(GroupTabButton *child);
virtual int getHeight();
virtual int childNotify(ifc_window *child, int msg, intptr_t param1 = 0, intptr_t param2 = 0);
void setMargin(int m) { margin = m; if (isInited()) onResize(); }
void setSpacing(int s) { spacing = s; if (isInited()) onResize(); }
private:
int maxheightsofar;
PtrList<GroupTabButton> btns;
int margin, spacing;
GuiObjectWnd bottombar;
};
#endif
+148
View File
@@ -0,0 +1,148 @@
#include "precomp.h"
#include "textbar.h"
#include <bfc/ifc_canvas.h>
#include <bfc/string/string.h>
#include <bfc/skinclr.h>
#include <bfc/autobitmap.h>
#include <common/checkwnd.h>
static SkinColor bgcolor("wasabi.textBar.background", "Text backgrounds");
static SkinColor fgcolor("wasabi.textBar.text");
TextBar::TextBar() {
size = 16;
usebt = 0;
alignment = TEXTALIGN_LEFT; //set default alignment
checkwndtarget = NULL;
textshadowed = 1; // display a shadow of the text in bgcolor. default: on
textoutlined = 0; // draw an outline of the text in bgcolor. default: off
drawbox = 0; // draw a box of bgcolor the size of the boundsrect. default: off
// bgbitmap = "studio.textBar.background";
}
int TextBar::onLeftButtonDown(int x, int y) {
TEXTBAR_PARENT::onLeftButtonDown(x, y);
if (checkwndtarget) checkwndtarget->toggle();
return 1;
}
void TextBar::setUseBaseTexture(int u) {
usebt = u;
invalidate();
}
int TextBar::onPaint(Canvas *canvas) {
RECT r;
PaintCanvas paintcanvas;
if (canvas == NULL) {
if (!paintcanvas.beginPaint(this)) return 0;
canvas = &paintcanvas;
}
TEXTBAR_PARENT::onPaint(canvas);
getClientRect(&r);
if (!usebt) {
if (drawbox) {
canvas->fillRect(&r, bgcolor);
}
/*
if (bgbitmap.getBitmap()->isInvalid())
canvas->fillRect(&r, bgcolor);
else {
RECT br;
br.left = 0;
br.top = 0;
br.right = bgbitmap.getWidth();
br.bottom = bgbitmap.getHeight();
bgbitmap.getBitmap()->blitToRect(canvas, &br, &r, 255);
}
*/
} else
renderBaseTexture(canvas, r);
const char *name = getName();
if (name != NULL) {
canvas->setTextOpaque(FALSE);
canvas->pushTextSize(size);
int w, h;
canvas->getTextExtent(name, &w, &h);
int y = (r.bottom-r.top - h) / 2;
// int x = centered ? (r.right-r.left - w) / 2 : TEXTBAR_LEFTMARGIN; //teh old code
int x = 0;
switch (alignment) {
default:
case TEXTALIGN_LEFT: x = TEXTBAR_LEFTMARGIN; break;
case TEXTALIGN_CENTER: x = (r.right-r.left - w) / 2; break;
case TEXTALIGN_RIGHT: x = (r.right-r.left - w); break;
}
if (!drawbox && textoutlined) {
canvas->setTextColor(bgcolor);
canvas->textOut(r.left+x+1, r.top+y+1, getName());
canvas->setTextColor(bgcolor);
canvas->textOut(r.left+x+1, r.top+y-1, getName());
canvas->setTextColor(bgcolor);
canvas->textOut(r.left+x-1, r.top+y+1, getName());
canvas->setTextColor(bgcolor);
canvas->textOut(r.left+x-1, r.top+y-1, getName());
} else if (!drawbox && textshadowed) {
canvas->setTextColor(bgcolor);
canvas->textOut(r.left+x+1, r.top+y+1, getName());
}
canvas->setTextColor(fgcolor);
canvas->textOut(r.left+x, r.top+y, getName());
canvas->popTextSize();
}
return 1;
}
int TextBar::setTextSize(int newsize) {
if (newsize < 1 || newsize > 72) return 0;
size = newsize;
invalidate();
return 1;
}
int TextBar::setInt(int i) {
setName(StringPrintf(i));
invalidate();
return 1;
}
void TextBar::onSetName() {
TEXTBAR_PARENT::onSetName();
invalidate();
}
int TextBar::getTextWidth() {
if (!getName()) return 0;
BltCanvas *c = new BltCanvas(10, 10);
c->pushTextSize(size);
int r = c->getTextWidth(getName());
c->popTextSize();
delete c;
return r+4;
}
int TextBar::getTextHeight() {
return size;
}
void TextBar::setAlign(TextAlign align) {
if (alignment != align) {
alignment = align;
invalidate();
}
}
TextAlign TextBar::getAlign() {
return alignment;
}
+219
View File
@@ -0,0 +1,219 @@
//PORTABLE
#ifndef _TEXTBAR_H
#define _TEXTBAR_H
#include <bfc/virtualwnd.h>
#include <bfc/autobitmap.h>
#include <bfc/textalign.h>
class CheckWnd;
#define TEXTBAR_PARENT VirtualWnd
/**
TextBar uses the BaseWnd name field of the object as the text
to be displayed.
@short TextBar control.
@author Nullsoft
@ver 1.0
@see LabelWnd
*/
class TextBar : public VirtualWnd {
public:
/**
Sets the default flags of the TextBar. Defaults to 16px fonts,
no background texture, left justified text, shadowed text in
the bgcolor, no outline, not box around the text.
*/
TextBar();
/**
Event is triggered when the window requires a repaint.
Override this to implement your own behavior.
Paints the bitmap on canvas according to current
options (centering, tiling, stretching, title).
@ret 0 for failure, 1 for success
@param canvas The canvas on which to paint.
*/
virtual int onPaint(Canvas *canvas);
/**
Event is triggered when the name of the window is changed.
Override this to implement your own behavior.
@see BaseWnd::setName()
*/
virtual void onSetName();
/**
Set the text to be displayed to an ascii representation of a numeric value.
@ret 1.
@param i The numeric value to be displayed.
*/
int setInt(int i);
/**
Set the size of the text for the textbar.
@ret 1, success; 0, failure.
@param newsize The new text size, range is from 1 to 72 pixels.
*/
int setTextSize(int newsize);
/**
Get the width of the text displayed, in pixels.
@ret Width of the displayed text (in pixels).
*/
int getTextWidth();
/**
Get the height of the text displayed, in pixels.
@ret Height of the displayed text.
*/
int getTextHeight();
/**
Use the base texture when rendering the TextBar?
If the base texture is used, it will be rendered as
the background of the textbar.
@param u !0, Use base texture; 0, Do not use base texture;
*/
void setUseBaseTexture(int u);
/**
Event is triggered when the left mouse button is pressed while
the textbar has focus. Override this to implement your
own behavior.
@param x X coordinate of the mouse pointer.
@param y Y coordinate of the mouse pointer.
*/
virtual int onLeftButtonDown(int x, int y);
/**
Center the text in the textbar? If not,
it will be left justified by default.
@param center !0, Center text; 0, Do not center text;
*/
// void setCenter(int center); //old code
/**
Get the center text flag.
@see setCenter()
@ret TRUE, Text is being centered; FALSE, No centering (left justified);
*/
// bool getCentered();
/**
Sets the alignment of the text to left, center, or right aligned
(possibly more later on, not too sure yet)
*/
void setAlign(TextAlign alignment);
/**
@ret returns the alignment of the text
*/
TextAlign getAlign();
// The following three options have ascending overriding priority --
/**
Sets the shadowed text flag. If enabled, the text will be shadowed
with the "bgcolor" value.
@see getTextShadowed()
@param settextshadowed !0, Shadow the text; 0, Do not shadow the text;
*/
void setTextShadowed(int settextshadowed) {
textshadowed = !!settextshadowed;
}
/**
Get the shadowed text flag. If enabled, the text will be shadowed
with the "bgcolor" value.
@see setTextShadowed()
@ret !0, Shadow the text; 0, Do not shadow the text;
*/
int getTextShadowed() {
return textshadowed;
}
/**
Sets the outline text flag. If enabled, the text will be
outlined with the "bgcolor" value.
@param settextoutlined !0, Outline the text; 0, Do not outline the text;
*/
void setTextOutlined(int settextoutlined) {
textoutlined = !!settextoutlined;
}
/**
Get the outline text flag. If enabled, the text will be
outlined with the "bgcolor" value.
@ret !0, Outline the text; 0, Do not outline the text;
*/
int getTextOutlined() {
return textoutlined;
}
/**
Set the drawbox flag. If true, the drawbox flag will cause
a box to be drawn around the text in the textbar.
@param setdrawbox !0, Drawbox around the text; 0, No drawbox;
*/
void setDrawBox(int setdrawbox) {
drawbox = !!setdrawbox;
}
/**
Get the drawbox flag. If true, the drawbox flag will cause
a box to be drawn around the text in the textbar.
@ret !0, Drawbox around the text; 0, No drawbox;
*/
int getDrawBox() {
return drawbox;
}
/**
Associate a checkbox with the textbar. When a textbar is linked
to a checkbox, it will toggle the checkbox when it receives
left clicks.
@param target A pointer to the CheckWnd to link.
*/
void setAutoToggleCheckWnd(CheckWnd *target) {
checkwndtarget = target;
}
private:
int size;
int usebt;
TextAlign alignment; //i changed this from centered, to a set text alignment thingie
int textshadowed; // display a shadow of the text in bgcolor. default: on
int textoutlined; // draw an outline of the text in bgcolor. default: off
int drawbox; // draw a box of bgcolor the size of the boundsrect. default: off
AutoSkinBitmap bgbitmap;
CheckWnd *checkwndtarget;
};
const int TEXTBAR_LEFTMARGIN = 2;
#endif
+47
View File
@@ -0,0 +1,47 @@
//#include <precomp.h>
#include "./api.h"
#include <api/wnd/api_wnd.h>
#include "tooltip.h"
#ifdef WASABI_COMPILE_CONFIG
#include <api/config/items/attrint.h>
#include <api/config/items/cfgitem.h>
#endif
#include <api/service/svc_enum.h>
Tooltip::Tooltip(const wchar_t *txt)
{
WASABI_API_WND->appdeactivation_push_disallow(NULL);
svc = NULL;
if (!txt || !*txt) return ;
#ifdef WASABI_COMPILE_CONFIG
// {9149C445-3C30-4e04-8433-5A518ED0FDDE}
const GUID uioptions_guid =
{ 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
if (!_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), L"Enable tooltips"))
{
// tooltips disabled
return ;
}
#endif
waServiceFactory *svf = WASABI_API_SVC->service_enumService(WaSvc::TOOLTIPSRENDERER, 0);
svc = castService<svc_toolTipsRenderer>(svf);
if (!svc)
{
// no tooltips available!
return ;
}
svc->spawnTooltip(txt);
}
Tooltip::~Tooltip()
{
if (svc != NULL)
WASABI_API_SVC->service_release(svc);
WASABI_API_WND->appdeactivation_pop_disallow(NULL);
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef __TOOLTIP_H
#define __TOOLTIP_H
#include <api/service/svcs/svc_tooltips.h>
class Tooltip {
public:
Tooltip(const wchar_t *txt);
virtual ~Tooltip();
private:
svc_toolTipsRenderer *svc;
};
#endif
File diff suppressed because it is too large Load Diff
+624
View File
@@ -0,0 +1,624 @@
#ifndef _TREEWND_H
#define _TREEWND_H
// BU: lots of changes
// - all items must be deletable, and will be deleted on destructor
// - root items list not allocated w/ new
// - items set sorting within their PtrListSorted instead of manually calling it
// - setting an item to auto-sort does *not* make subitems autosort too
#include <api/wnd/wndclass/scbkgwnd.h>
#include <bfc/ptrlist.h>
#include <api/wnd/wndclass/editwnd.h>
#include <bfc/common.h>
#include <tataki/color/skinclr.h>
#define TREEWND_PARENT ScrlBkgWnd
#define STATUS_EXPANDED 0
#define STATUS_COLLAPSED 1
#define HITTEST_BEFORE 0
#define HITTEST_IN 1
#define HITTEST_AFTER 2
#define LINK_RIGHT 1
#define LINK_TOP 2
#define LINK_BOTTOM 4
#define TAB_NO FALSE
#define TAB_YES TRUE
#define TAB_AUTO 2
#define WM_SETITEMDEFERRED WM_USER+6546
#define DC_SETITEM 10
#define DC_DELITEM 20
#define DC_EXPAND 30
#define DC_COLLAPSE 40
// Forward references
class TreeItemList;
class TreeItem;
class TreeWnd;
class FontSize;
// classes & structs
class CompareTreeItem {
public:
static int compareItem(TreeItem *p1, TreeItem *p2);
};
class TreeItemList : public PtrListQuickSorted<TreeItem, CompareTreeItem> { };
class TreeItem
{
friend class TreeWnd;
public:
TreeItem(const wchar_t *label=NULL);
virtual ~TreeItem();
virtual SkinBitmap *getIcon();
virtual void setIcon(SkinBitmap *newicon);
virtual void onTreeAdd() {}
virtual void onTreeRemove() {}
virtual void onChildItemRemove(TreeItem *item) {}
// override this to keep from being selected
virtual int isHitTestable() { return 1; }
virtual void onSelect() {}
virtual void onDeselect() {}
virtual int onLeftDoubleClick() { return 0; }
virtual int onRightDoubleClick() { return 0; }
virtual int onContextMenu(int x, int y);
virtual int onChar(UINT key) { return 0; } // return 1 if you eat the key
// these are called after the expand/collapse happens
virtual void onExpand() {}
virtual void onCollapse() {}
virtual int onBeginLabelEdit();
virtual int onEndLabelEdit(const wchar_t *newlabel);
virtual void setLabel(const wchar_t *label);
virtual const wchar_t *getLabel();
void setTip(const wchar_t *tip);
const wchar_t *getTip();
// override to draw by yourself. Return the width of what you've drawn
virtual int customDraw(Canvas *canvas, const POINT &pt, int defaultTxtHeight, int indentation, const RECT &clientRect, const Wasabi::FontInfo *fontInfo);
// return 0 to refuse being dragged
// else return 1 and install the droptype and dropitem
// also, write suggested title into suggestedTitle if any
virtual int onBeginDrag(wchar_t *suggestedTitle) { return 0; }
virtual int dragOver(ifc_window *sourceWnd) { return 0; }
virtual int dragLeave(ifc_window *sourceWnd) { return 0; }
virtual int dragDrop(ifc_window *sourceWnd) { return 0; }
virtual int dragComplete(int success) { return 0; }
void ensureVisible();
TreeItem *getNthChild(int nth); // enumerates children (zero based)
TreeItem *getChild();
TreeItem *getChildSibling(TreeItem *item);
TreeItem *getSibling();
TreeItem *getParent();
void editLabel();
int getNumChildren();
bool hasSubItems();
void setSorted(int issorted);
void setChildTab(int haschildtab);
bool isSorted();
bool isCollapsed();
bool isExpanded();
void invalidate();
bool isSelected();
bool isHilited();
void setHilited(bool ishilited);
int collapse();
int expand();
int getCurRect(RECT *r);
void setCurrent(bool tf);
TreeWnd *getTree() const;
protected:
bool isHilitedDrop();
void setHilitedDrop(bool ishilitedDrop);
void linkTo(TreeItem *linkto);
// void childDeleted(TreeItem *child);
void setTree(TreeWnd *newtree);
void addSubItem(TreeItem *item);
void setCurRect(int x1, int y1, int x2, int y2, int z);
int getIndent();
bool needTab();
void sortItems(); // sorts the children of this item
void setEdition(bool isedited);
bool getEdition();
private:
void setSelected(bool isselected, bool expandCollapse=false, bool editifselected=false);
// this really calls delete on the subitems
void deleteSubitems();
int removeSubitem(TreeItem *item);
int getItemWidth(int txtHeight, int indentation);
StringW label;
class TreeItem *parent;
TreeItemList subitems; // children
RECT curRect;
int childTab;
TreeWnd *tree;
int expandStatus;
SkinBitmap *icon;
int _z;
StringW tooltip; // if empty, falls back to livetip
bool selected:1;
bool hilitedDrop:1;
bool hilited:1;
bool being_edited:1;
};
/**
@short Tree-like view with leaf items.
@ver 1.0
@author Nullsoft
@see TreeItem
*/
class TreeWnd : public TREEWND_PARENT {
friend class TreeItem;
public:
/**
Sets up the default values for the TreeWnd. These defaults are
auto collapse enabled and sets the TreeWnd bitmaps to the default Wasabi
values.
*/
TreeWnd();
/**
Deletes all the root items (including subitems).
*/
virtual ~TreeWnd();
/**
Event is triggered when the button is about to be initialized.
Override this event to implement your own behavior.
@ret 1
*/
virtual int onInit();
/**
Paints the bitmap on canvas according
to current options (centering, tiling, stretching, title).
@ret 0 for failure, 1 for success
@param canvas The canvas on which to paint.
*/
virtual int onPaint(Canvas *canvas);
/**
Notify a child window via a generic message system.
@see addChild()
@ret
@param child A pointer to the child window which will receive the notify.
@param msg The message you want to send to the child.
@param p1 A user parameter.
@param p2 A user parameter.
*/
virtual int childNotify(ifc_window *child, int msg, intptr_t param1=0, intptr_t param2=0);
/**
Event triggered when the left mouse
button is pressed over the TreeWnd.
Override this to implement your own behavior.
Default behavior is to stop editing a TreeItem label
(if editing was occuring). Also will cause a collapse
or expansion of the subitems if an item was previously
selected.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonDown(int x, int y);
/**
Event is triggered when the left mouse button
is released from a previously pressed state.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonUp(int x, int y);
/**
Event is triggered when the right mouse button
is released from a previously pressed state.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onRightButtonUp(int x, int y);
/**
Event is triggered when the mouse is moved
over the TreeWnd.
Override this to implement your own behavior.
Default is to handle drops (drag and drop).
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onMouseMove(int x, int y);
/**
Do we want the context command menu to pop-up
on right clicks?
Default is no.
@see ContextCmdI
@ret 0, AutoContextMenu off; 1, AutoContextMenu on;
*/
virtual int wantAutoContextMenu() { return 0; }
/**
Event is triggered when the left mouse button
is double clicked and the cursor is over the
TreeWnd.
Default is to check if the doubleclick
happened over an item, if it did, it calls
the item's handler of this event.
@ret 1, if you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onLeftButtonDblClk(int x, int y);
/**
Event is triggered when the right mouse button
is double clicked and the cursor is over the
TreeWnd.
Default is to check if the doubleclick
happened over an item, if it did, it calls
the item's handler of this event.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The y coordinate of the mouse.
*/
virtual int onRightButtonDblClk(int x, int y);
/**
Event is triggered when the mouse wheel
is rolled up.
Override this to implement your own behavior.
Default is to scroll vertically as required.
When the wheel is clicked and rolled, the
TreeWnd is scrolled horizontally.
@ret 1, If you handle the event.
@param clicked The pushed state of the mouse wheel.
@param lines The number of lines to scroll (or columns if horizontally scrolling).
*/
virtual int onMouseWheelUp(int clicked, int lines);
/**
Event is triggered when the mouse wheel
is rolled down.
Override this to implement your own behavior.
Default is to scroll vertically as required.
When the wheel is clicked and rolled, the
TreeWnd is scrolled horizontally.
@ret 1, If you handle the event.
@param clicked The pushed state of the mouse wheel.
@param lines The number of lines to scroll (or columns if horizontally scrolling).
*/
virtual int onMouseWheelDown(int clicked, int lines);
/**
*/
virtual void timerCallback(int c);
/**
Event is triggered when the right click occurs over
the TreeWnd, but not on a TreeItem.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param x The X coordinate of the mouse.
@param y The Y coordinate of the mouse.
*/
virtual int onContextMenu(int x, int y);
// override and return 1 to abort calling context menu on item
virtual int onPreItemContextMenu(TreeItem *item, int x, int y) { return 0; }
// override to catch when item context menu complete
virtual void onPostItemContextMenu(TreeItem *item, int x, int y, int retval) { }
/**
Event is triggered when a scheduled deferred callback
occurs.
Override this to implement your own behavior.
@ret 1, If you handle this event; 0, If you do not handle this event;
@param param1 Generic user paramater 1.
@param param2 Generic user paramater 2.
*/
virtual int onDeferredCallback(intptr_t param1, intptr_t param2);
/**
Event is triggered when a key is pressed
and the TreeWnd has focus.
Override this to implement your own behavior.
@ret 1, If you handle the event.
@param c The key that was pressed.
*/
virtual int onChar(unsigned int c);
/**
Event is triggered when a key is pressed
and the TreeWnd has focus.
This method handles extended keys.
@ret 1, If you handle the event.
*/
virtual int onKeyDown(int keycode);
/**
*/
virtual void jumpToNext(wchar_t c);
/**
Verifies if the item received is in the
viewable area of the TreeWnd. If not, it
will make it visible by scrolling to the
appropriate position.
@param item A pointer to the item to verify.
*/
void ensureItemVisible(TreeItem *item);
// don't need to override this: just calls thru to the treeitem
virtual int onBeginDrag(TreeItem *treeitem);
virtual int dragEnter(ifc_window *sourceWnd);
virtual int dragOver(int x, int y, ifc_window *sourceWnd);
virtual int dragLeave(ifc_window *sourceWnd);
virtual int dragDrop(ifc_window *sourceWnd, int x, int y);
virtual int dragComplete(int success);
int wantFocus() { return 1; }
// override this if you want to control the item sort order
virtual int compareItem(TreeItem *p1, TreeItem *p2);
protected:
// these will be called if the pointer is not over a treeitem
virtual int defaultDragOver(int x, int y, ifc_window *sourceWnd) { return 0; }
virtual int defaultDragDrop(ifc_window *sourceWnd, int x, int y) { return 0; }
// called with item that received a drop
virtual void onItemRecvDrop(TreeItem *item) {}
virtual void onLabelChange(TreeItem *item) {}
virtual void onItemSelected(TreeItem *item) {}
virtual void onItemDeselected(TreeItem *item) {}
virtual int onGetFocus();
virtual int onKillFocus();
public:
virtual int getContentsWidth();
virtual int getContentsHeight();
void setRedraw(bool r);
TreeItem *addTreeItem(TreeItem *item, TreeItem *par=NULL, int sorted=TRUE, int haschildtab=FALSE);
// just removes a TreeItem from the tree, doesn't delete it... this is for
// ~TreeItem to call only
int removeTreeItem(TreeItem *item);
void moveTreeItem(TreeItem *item, TreeItem *newparent);
void deleteAllItems();
int expandItem(TreeItem *item);
void expandItemDeferred(TreeItem *item);
int collapseItem(TreeItem *item);
void collapseItemDeferred(TreeItem *item);
void selectItem(TreeItem *item); // selects.
void selectItemDeferred(TreeItem *item);// selects. posted.
void delItemDeferred(TreeItem *item);
void hiliteItem(TreeItem *item);
void unhiliteItem(TreeItem *item);
void setHilitedColor(const wchar_t *colorname);
ARGB32 getHilitedColor();
TreeItem *getCurItem();
TreeItem *hitTest(POINT pos);
TreeItem *hitTest(int x, int y);
void editItemLabel(TreeItem *item);
void cancelEditLabel(int destroyit=0);
void setAutoEdit(int ae);
int getAutoEdit();
// use a NULL item to search all items. returns first item found
TreeItem *getByLabel(TreeItem *item, const wchar_t *name);
int getItemRect(TreeItem *item, RECT *r);
int ownerDraw();
int getNumRootItems();
TreeItem *enumRootItem(int which);
void setSorted(bool dosort);
bool getSorted();
void sortTreeItems();
TreeItem *getSibling(TreeItem *item);
TreeItem *getItemFromPoint(POINT *pt);
void setAutoCollapse(bool doautocollapse);
virtual int setFontSize(int newsize);
int getFontSize();
int getNumVisibleChildItems(TreeItem *c);
int getNumVisibleItems();
TreeItem *enumVisibleItems(int n);
TreeItem *enumVisibleChildItems(TreeItem *c, int n);
int findItem(TreeItem *i); // reverse
int findChildItem(TreeItem *c, TreeItem *i, int *n);
TreeItem *enumAllItems(int n); // unsorted
void onSelectItem(TreeItem *i);
void onDeselectItem(TreeItem *i);
protected:
void hiliteDropItem(TreeItem *item);
void unhiliteDropItem(TreeItem *item);
void invalidateMetrics();
private:
TreeItemList items; // root-level stuff
PtrList<TreeItem> all_items; // unsorted
TreeItem *curSelected;
BltCanvas *dCanvas;
void drawItems(Canvas *c, const Wasabi::FontInfo *fontInfo);
void setCurItem(TreeItem *item, bool expandCollapse=true, bool editifselected=false);
void countSubItems(PtrList<TreeItem> &drawlist, TreeItemList *list, int indent, int *c, int *m, int z);
void getMetrics(int *numItemsShow, int *maxWidth);
void ensureMetricsValid();
int getLinkLine(TreeItem *item, int level);
void endEditLabel(const wchar_t *newlabel);
void editUpdate();
int jumpToNextSubItems(TreeItemList *list, wchar_t c);
int itemHeight;
AutoSkinBitmap tabClosed, tabOpen;
AutoSkinBitmap linkTopRight, linkTopBottom, linkTopRightBottom;
AutoSkinBitmap linkTabTopRight, linkTabTopBottom, linkTabTopRightBottom;
TreeItem *firstItemVisible;
TreeItem *lastItemVisible;
TreeItem *mousedown_item, *prevbdownitem;
POINT mousedown_anchor;
bool mousedown_dragdone;
TreeItem *hitItem, // the dest item
*draggedItem; // the source item
int inHitTest;
bool metrics_ok;
int maxWidth;
int maxHeight;
StringW defaultTip;
const wchar_t *getLiveTip();
void setLiveTip(const wchar_t *tip);
TreeItem *tipitem;
bool redraw;
PtrList<TreeItem> drawList;
TreeItem *edited;
EditWnd *editwnd;
wchar_t editbuffer[256];
int deleteItems;
bool firstFound;
TreeItem *currentItem;
StringW hilitedColorName;
SkinColor hilitedColor;
int autoedit;
int autocollapse;
int textsize;
StringW oldtip;
StringW accValue;
};
template<class T> class TreeItemParam : public TreeItem {
public:
TreeItemParam(T _param, const wchar_t *label=NULL) : TreeItem(label) { param = _param; }
T getParam() { return param; }
operator T() { return getParam(); }
private:
T param;
};
#endif
+38
View File
@@ -0,0 +1,38 @@
#include <precomp.h>
#include "typesheet.h"
#include <api/wnd/wndclass/svcwndhold.h>
#include <api/wnd/wndclass/buttbar.h>
#include <api/service/svcs/svc_wndcreate.h>
TypeSheet::TypeSheet(const wchar_t *_windowtype) :
TabSheet(ButtBar::STACK), windowtype(_windowtype)
{ }
int TypeSheet::onInit() {
TYPESHEET_PARENT::onInit();
load();
return 1;
}
void TypeSheet::setWindowType(const wchar_t *wtype) {
windowtype = wtype;
}
void TypeSheet::load() {
if (windowtype == NULL || !*windowtype) return;
WindowCreateByTypeEnum se(windowtype);
svc_windowCreate *svc;
while (svc = se.getNext()) {
for (int i = 0; ; i++) {
ServiceWndHolder *svcwnd = new ServiceWndHolder;
ifc_window *wnd = svc->createWindowOfType(windowtype, svcwnd, i);
if (wnd == NULL) {
delete svcwnd;
break;
}
svcwnd->setChild(wnd, svc);
addChild(svcwnd);
}
}
}
+49
View File
@@ -0,0 +1,49 @@
#ifndef _TYPESHEET_H
#define _TYPESHEET_H
#include "tabsheet.h"
#define TYPESHEET_PARENT TabSheet
/**
Class TypeSheet
@short A Typesheet Control.
@author Nullsoft
@ver 1.0
@see
*/
class TypeSheet : public TYPESHEET_PARENT {
public:
/**
TypeSheet constructor
@param _windowtype
*/
TypeSheet(const wchar_t *windowtype);
/**
TypeSheet method onInit .
@ret 1
@param None
*/
virtual int onInit();
/**
TypeSheet method load
*/
virtual void load();
/**
TypeSheet method setWindowType .
@param windowtype The type of the window.
*/
virtual void setWindowType(const wchar_t *windowtype);
private:
StringW windowtype;
};
#endif
@@ -0,0 +1,198 @@
#include "precomp.h"
#include "virtualhostwnd.h"
#include <tataki/canvas/ifc_canvas.h>
#include <tataki/region/api_region.h>
VirtualHostWnd::VirtualHostWnd() {
group = new GuiObjectWnd();
fittoclient = 0;
xoffset = 0;
yoffset = 0;
groupwidth = 0;
groupheight = 0;
scripts_enabled = 1;
}
VirtualHostWnd::~VirtualHostWnd() {
delete group;
}
int VirtualHostWnd::onInit() {
GuiObjectWnd::onInit();
group->setVirtual(0);
group->setStartHidden(1);
group->setParent(this);
group->init(this);
group->deferedInvalidate();
group->setCloaked(1); // magic!
group->setVisible(1);
return 1;
}
void VirtualHostWnd::virtualhostwnd_setContent(const char *_groupname) {
group->setContent(_groupname);
if (isPostOnInit())
virtualhostwnd_onNewContent();
}
void VirtualHostWnd::virtualhostwnd_setContent(SkinItem *groupitem) {
group->setContentBySkinItem(groupitem);
if (isPostOnInit())
virtualhostwnd_onNewContent();
}
void VirtualHostWnd::virtualhostwnd_onNewContent() {
}
#ifdef WASABI_COMPILE_SCRIPT
ScriptObject *VirtualHostWnd::virtualhostwnd_findScriptObject(const char *object_id) {
return group->findScriptObject(object_id);
}
#endif
#ifdef WASABI_COMPILE_SKIN
GuiObject *VirtualHostWnd::virtualhostwnd_getContent() {
return group->getContent();
}
ScriptObject *VirtualHostWnd::virtualhostwnd_getContentScriptObject() {
return group->getContentScriptObject();
}
GuiObject *VirtualHostWnd::virtualhostwnd_findObject(const char *object_id) {
return group->findObject(object_id);
}
#endif
api_window *VirtualHostWnd::virtualhostwnd_getContentRootWnd() {
return group->getContentRootWnd();
}
int VirtualHostWnd::onPaint(Canvas *c) {
GuiObjectWnd::onPaint(c);
virtualhostwnd_onPaintBackground(c);
if (group == NULL) return 1;
RECT wr;
Canvas *cv = NULL;
group->getNonClientRect(&wr);
group->paint(NULL, NULL);
cv = group->getFrameBuffer();
if (cv != NULL) {
BltCanvas *bltcanvas = static_cast<BltCanvas *>(cv); // HACK!
bltcanvas->/*getSkinBitmap()->*/blitAlpha(c, xoffset, yoffset);
}
return 1;
}
void VirtualHostWnd::virtualhostwnd_onPaintBackground(Canvas *c) {
RECT r;
getClientRect(&r);
c->fillRect(&r, RGB(255,255,255));
}
int VirtualHostWnd::onResize() {
GuiObjectWnd::onResize();
if (group != NULL) {
RECT r;
getClientRect(&r);
if (fittoclient) {
xoffset = 0;
yoffset = 0;
groupwidth = r.right-r.left;
groupheight = r.bottom-r.top;
} else {
groupwidth = group->getGuiObject()->guiobject_getAutoWidth();
groupheight = group->getGuiObject()->guiobject_getAutoHeight();
if (groupwidth == AUTOWH) groupwidth = 320;
if (groupheight == AUTOWH) groupheight = 200;
int cw = r.right-r.left;
int ch = r.bottom-r.top;
xoffset = (cw - groupwidth)/2;
yoffset = (ch - groupheight)/2;
}
group->resize(xoffset+r.left, yoffset+r.top, groupwidth, groupheight);
}
return 1;
}
void VirtualHostWnd::virtualhostwnd_getContentRect(RECT *r) {
ASSERT(r != NULL);
getClientRect(r);
r->left += xoffset;
r->top += yoffset;
r->right = r->left + groupwidth;
r->bottom = r->top + groupheight;
}
void VirtualHostWnd::virtualhostwnd_fitToClient(int fit) {
fittoclient = fit;
if (isPostOnInit()) {
onResize();
invalidate();
}
}
void VirtualHostWnd::onChildInvalidate(api_region *r, api_window *who) {
GuiObjectWnd::onChildInvalidate(r, who);
api_region *clone = r->clone();
clone->offset(xoffset, yoffset);
invalidateRgn(clone);
r->disposeClone(clone);
}
int VirtualHostWnd::onLeftButtonDown(int x, int y) {
// DO NOT CALL GuiObjectWnd::onLeftButtonDown(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
}
int VirtualHostWnd::onLeftButtonUp(int x, int y){
// DO NOT CALL GuiObjectWnd::onLeftButtonUp(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_LBUTTONUP, 0, MAKELPARAM(x, y));
}
int VirtualHostWnd::onRightButtonDown(int x, int y){
// DO NOT CALL GuiObjectWnd::onRightButtonDown(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(x, y));
}
int VirtualHostWnd::onRightButtonUp(int x, int y){
// DO NOT CALL GuiObjectWnd::onRightButtonUp(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_RBUTTONUP, 0, MAKELPARAM(x, y));
}
int VirtualHostWnd::onLeftButtonDblClk(int x, int y){
// DO NOT CALL GuiObjectWnd::onLeftButtonDblClk(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_RBUTTONDBLCLK, 0, MAKELPARAM(x, y));
}
int VirtualHostWnd::onRightButtonDblClk(int x, int y){
// DO NOT CALL GuiObjectWnd::onRightButtonDblClk(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_LBUTTONDBLCLK, 0, MAKELPARAM(x, y));
}
int VirtualHostWnd::onMouseMove(int x, int y){
// DO NOT CALL GuiObjectWnd::onMouseMove(x, y);
x -= xoffset;
y -= yoffset;
return group->wndProc(group->gethWnd(), WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
}
@@ -0,0 +1,51 @@
#ifndef __VIRTUALHOSTWND_H
#define __VIRTUALHOSTWND_H
#include "../../common/guiobjwnd.h"
class VirtualHostWnd : public GuiObjectWnd {
public:
VirtualHostWnd();
virtual ~VirtualHostWnd();
virtual int onInit();
virtual int onPaint(Canvas *c);
virtual int onResize();
virtual void onChildInvalidate(api_region *r, ifc_window *who);
virtual int onLeftButtonDown(int x, int y);
virtual int onLeftButtonUp(int x, int y);
virtual int onRightButtonDown(int x, int y);
virtual int onRightButtonUp(int x, int y);
virtual int onLeftButtonDblClk(int x, int y);
virtual int onRightButtonDblClk(int x, int y);
virtual int onMouseMove(int x, int y);
virtual void virtualhostwnd_setContent(const wchar_t *groupid);
virtual void virtualhostwnd_setContent(SkinItem *item);
virtual void virtualhostwnd_onNewContent();
virtual void virtualhostwnd_onPaintBackground(Canvas *c);
virtual void virtualhostwnd_fitToClient(int fit);
virtual void virtualhostwnd_getContentRect(RECT *r);
virtual ifc_window *virtualhostwnd_getContentRootWnd();
#ifdef WASABI_COMPILE_SCRIPT
virtual ScriptObject *virtualhostwnd_findScriptObject(const wchar_t *object_id);
#endif
#ifdef WASABI_COMPILE_SKIN
virtual GuiObject *virtualhostwnd_findObject(const wchar_t *object_id);
virtual GuiObject *virtualhostwnd_getContent();
virtual ScriptObject *virtualhostwnd_getContentScriptObject();
#endif
private:
GuiObjectWnd *group;
int fittoclient;
int xoffset, yoffset;
int groupwidth, groupheight;
int scripts_enabled;
};
#endif
+369
View File
@@ -0,0 +1,369 @@
#include <precomp.h>
#include "wndholder.h"
#include <api/service/svcs/svc_wndcreate.h>
#include <api/service/svc_enum.h>
#include <api/syscb/callbacks/wndcb.h>
//#pragma CHAT("lone", "benski", "needs to dispatch Layout & Containers!")
#include <api/wndmgr/container.h>
#include <api/wndmgr/layout.h>
#define CBCLASS WindowHolderI
START_DISPATCH;
CB(WNDHOLDER_ONINSERTWINDOW, onInsertWindow);
VCB(WNDHOLDER_ONREMOVEWINDOW, onRemoveWindow);
CB(WNDHOLDER_WANTGUID, wantGuid);
CB(WNDHOLDER_WANTGROUP, wantGroup);
CB(WNDHOLDER_GETROOTWNDPTR, getRootWndPtr);
CB(WNDHOLDER_GETCURGROUPID, getCurGroupId);
CB(WNDHOLDER_GETCURGUID, getCurGuid);
CB(WNDHOLDER_GETCURROOTWND, getCurRootWnd);
CB(WNDHOLDER_GETCURID, getCurId);
CB(WNDHOLDER_ISGENERICGUID, acceptsGenericGuid);
CB(WNDHOLDER_ISGENERICGROUP, acceptsGenericGroup);
VCB(WNDHOLDER_CANCELDEFERREDREMOVE, cancelDeferredRemove);
VCB(WNDHOLDER_ONNEEDRELOADGRP, wndholder_onNeedReloadGroup);
CB(WNDHOLDER_WANTAUTOFOCUS, wndholder_wantAutoFocus);
CB(WNDHOLDER_ISAUTOAVAILABLE, wndholder_isAutoAvailable);
END_DISPATCH;
WindowHolderI::WindowHolderI() {
wnd = NULL;
dr = NULL;
generic_guid = 1;
generic_group = 1;
cur_guid = INVALID_GUID;
cur_groupid = NULL;
wc_svc = NULL;
WASABI_API_WNDMGR->wndholder_register(this);
}
WindowHolderI::~WindowHolderI() {
delete dr;
if (wnd != NULL) {
if (wc_svc) {
ifc_window *w = wnd;
wnd = NULL;
wc_svc->destroyWindow(w);
SvcEnum::release(wc_svc);
wc_svc = NULL;
} else {
ifc_window *w = wnd;
wnd = NULL;
WASABI_API_SKIN->group_destroy(w);
}
}
accepted_groups.deleteAll();
accepted_guids.deleteAll();
WASABI_API_WNDMGR->wndholder_unregister(this);
}
ifc_window *WindowHolderI::onInsertWindow(GUID g, const wchar_t *groupid)
{
cancelDeferredRemove();
defered_guid = INVALID_GUID;
if (wnd != NULL) return NULL;
cur_groupid = groupid;
if (g != INVALID_GUID)
{
cur_guid = g;
wchar_t cguid[256] = {0};
nsGUID::toCharW(g, cguid);
cur_id = cguid;
} else
cur_id = groupid;
wnd = createWindow(g == INVALID_GUID ? NULL : &g, groupid);
if (!wnd) {
cur_guid = INVALID_GUID;
cur_id = L"";
cur_groupid = L"";
}
if (wnd) {
onInsert(wnd, cur_id);
} else {
if (g != INVALID_GUID) {
defered_guid = g;
}
}
return wnd;
}
void WindowHolderI::onRemoveWindow(int deferred) {
if (deferred) {
if (!dr)
dr = new DeferredRemove(this);
dr->post();
return;
}
if (wnd != NULL) {
ifc_window *w = getCurRootWnd();
onRemove(w, cur_id);
destroyWindow();
cur_guid = INVALID_GUID;
cur_groupid = NULL;
defered_guid = INVALID_GUID;
}
}
void WindowHolderI::cancelDeferredRemove() {
delete dr;
dr = NULL;
}
void WindowHolderI::wndholder_onNeedReloadGroup(const wchar_t *id)
{
if (cur_groupid.isempty()) return;
ifc_window *w = getCurRootWnd();
if (w == NULL) return;
if (w->isInited() && !WCSICMP(cur_groupid, id))
{
onRemove(w, cur_id);
destroyWindow();
createWindow(&INVALID_GUID, id);
onInsert(wnd, cur_id);
}
}
ifc_window *WindowHolderI::createWindow(const GUID *g, const wchar_t *groupid)
{
ASSERT(wnd == NULL);
if (g != NULL && *g != INVALID_GUID) {
wc_svc = WindowCreateByGuidEnum(*g).getFirst();
if (wc_svc)
wnd = wc_svc->createWindowByGuid(*g, getRootWndPtr());
}
else if (groupid != NULL)
{
wc_svc = NULL;
wnd = WASABI_API_SKIN->group_create(groupid);
}
if (wnd) {
if (!wnd->isInited()) {
if (!wnd->getParent()) wnd->setParent(getRootWndPtr());
wnd->init(getRootWndPtr());
}
}
return wnd;
}
void WindowHolderI::destroyWindow() {
ASSERT(wnd != NULL);
ifc_window *w = wnd->getDesktopParent();
if (wc_svc) {
ifc_window *w = wnd;
wnd = NULL;
wc_svc->destroyWindow(w);
SvcEnum::release(wc_svc);
wc_svc = NULL;
} else {
ifc_window *w = wnd;
wnd = NULL;
WASABI_API_SKIN->group_destroy(w);
}
if (w != NULL) {
if (w->getInterface(layoutGuid)) {
static_cast<Layout *>(w)->updateTransparency();
}
}
}
void WindowHolderI::addAcceptGuid(GUID g) {
accepted_guids.addItem(new GUID(g));
}
void WindowHolderI::addAcceptGroup(const wchar_t *groupid)
{
accepted_groups.addItem(new StringW(groupid));
}
void WindowHolderI::setAcceptAllGuids(int tf) {
generic_guid = tf;
}
void WindowHolderI::setAcceptAllGroups(int tf) {
generic_group = tf;
}
int WindowHolderI::wantGuid(GUID g) {
if (acceptsGenericGuid()) return 1;
for (int i=0;i<accepted_guids.getNumItems();i++) {
if (*accepted_guids.enumItem(i) == g) return 1;
}
return 0;
}
int WindowHolderI::wantGroup(const wchar_t *groupid)
{
if (acceptsGenericGroup()) return 1;
for (int i=0;i<accepted_groups.getNumItems();i++) {
if (!WCSICMP(accepted_groups.enumItem(i)->getValue(), groupid))
return 1;
}
return 0;
}
GUID *WindowHolderI::getFirstAcceptedGuid() {
if (accepted_guids.getNumItems() == 0) return NULL;
return accepted_guids.enumItem(0);
}
const wchar_t *WindowHolderI::getFirstAcceptedGroup()
{
if (accepted_guids.getNumItems() == 0)
return NULL;
return
accepted_groups.enumItem(0)->getValue();
}
int WindowHolderI::wndholder_wantAutoFocus() {
return 1;
}
WindowHolderWnd::WindowHolderWnd() {
autoavail = 1;
autoopen = 1;
autoclose = 0;
nocmdbar = 0;
noanim = 0;
has_wnd = 0;
autofocus = 1;
WASABI_API_SYSCB->syscb_registerCallback(this);
}
WindowHolderWnd::~WindowHolderWnd() {
if (has_wnd) {
notifyOnRemove();
}
WASABI_API_SYSCB->syscb_deregisterCallback(this);
}
int WindowHolderWnd::onResize() {
WINDOWHOLDER_PARENT::onResize();
if (getCurRootWnd()) {
RECT r;
getClientRect(&r);
if (!getCurRootWnd()->handleRatio())
multRatio(&r);
getCurRootWnd()->resize(r.left, r.top, r.right-r.left, r.bottom-r.top);
}
return 1;
}
int WindowHolderWnd::handleRatio() {
return 1;
}
int WindowHolderWnd::handleDesktopAlpha() {
if (getCurRootWnd()) return getCurRootWnd()->handleDesktopAlpha();
return 1;
}
int WindowHolderWnd::handleTransparency() {
if (getCurRootWnd()) return getCurRootWnd()->handleTransparency();
return 1;
}
int WindowHolderWnd::onInit() {
WINDOWHOLDER_PARENT::onInit();
if (isVisible() && autoopen && getFirstAcceptedGuid()) {
onInsertWindow(*getFirstAcceptedGuid(), NULL);
} else if (isVisible() && autoopen && getFirstAcceptedGroup()) {
onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
}
return 1;
}
#define DC_NOTIFYONREMOVE 0x205
void WindowHolderWnd::onRemove(ifc_window *w, const wchar_t *id)
{
ifc_window *dw = getDesktopParent();
if (dw) dw->removeMinMaxEnforcer(this);
postDeferredCallback(DC_NOTIFYONREMOVE);
}
int WindowHolderWnd::onDeferredCallback(intptr_t p1, intptr_t p2) {
if (p1 == DC_NOTIFYONREMOVE) {
notifyOnRemove();
} else return WINDOWHOLDER_PARENT::onDeferredCallback(p1, p2);
return 1;
}
void WindowHolderWnd::onInsert(ifc_window *w, const wchar_t *id)
{
if (isPostOnInit())
onResize();
ifc_window *dw = getDesktopParent();
if (dw) dw->addMinMaxEnforcer(this);
notifyOnInsert();
if (wndholder_wantAutoFocus()) w->setFocus();
}
int WindowHolderWnd::getPreferences(int what) {
if (getCurRootWnd()) return getCurRootWnd()->getPreferences(what);
return WINDOWHOLDER_PARENT::getPreferences(what);
}
void WindowHolderWnd::notifyOnRemove() {
has_wnd = 0;
Layout *l = getGuiObject()->guiobject_getParentLayout();
if (l != NULL) {
Container *c = l->getParentContainer();
if (c != NULL) {
c->notifyRemoveContent(this);
}
}
}
void WindowHolderWnd::notifyOnInsert() {
has_wnd = 1;
Layout *l = getGuiObject()->guiobject_getParentLayout();
if (l != NULL) {
Container *c = l->getParentContainer();
if (c != NULL)
{
c->notifyAddContent(this, getCurGroupId(), getCurGuid());
}
}
}
int WindowHolderWnd::onGroupChange(const wchar_t *grpid)
{
WINDOWHOLDER_PARENT::onGroupChange(grpid);
wndholder_onNeedReloadGroup(grpid);
return 1;
}
void WindowHolderWnd::onSetVisible(int show) {
if (show && getCurRootWnd() == NULL) {
if (autoopen && getFirstAcceptedGuid()) {
onInsertWindow(*getFirstAcceptedGuid(), NULL);
} else if (autoopen && getFirstAcceptedGroup()) {
onInsertWindow(INVALID_GUID, getFirstAcceptedGroup());
}
} else if (!show && getCurRootWnd() != NULL) {
if (autoclose && WASABI_API_SKIN->skin_getVersion() >= 1.0)
onRemoveWindow(0);
}
if (getDeferedGuid() != INVALID_GUID) {
if (show) {
#ifdef ON_CREATE_EXTERNAL_WINDOW_GUID
int y;
ON_CREATE_EXTERNAL_WINDOW_GUID(getDeferedGuid(), y);
#endif
}
}
WINDOWHOLDER_PARENT::onSetVisible(show);
}
int WindowHolderWnd::wndholder_wantAutoFocus() {
return autofocus;
}
+285
View File
@@ -0,0 +1,285 @@
#ifndef __WINDOWHOLDER_H
#define __WINDOWHOLDER_H
#include <api/wnd/wndclass/guiobjwnd.h>
#include <bfc/ptrlist.h>
#include <api/syscb/callbacks/wndcb.h>
#include <api/timer/timerclient.h>
class svc_windowCreate;
#define WINDOWHOLDER_PARENT GuiObjectWnd
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class WindowHolder : public Dispatchable
{
public:
ifc_window *onInsertWindow(GUID g, const wchar_t *groupid);
void onRemoveWindow(int deferred=0);
int wantGuid(GUID g);
int wantGroup(const wchar_t *groupid);
GUID getCurGuid();
const wchar_t *getCurGroupId();
ifc_window *getCurRootWnd();
const wchar_t *getCurId();
ifc_window *getRootWndPtr();
int acceptsGenericGuid();
int acceptsGenericGroup();
int wndholder_getPreferences(int what);
void wndholder_onNeedReloadGroup(const wchar_t *id);
void cancelDeferredRemove();
int wndholder_wantAutoFocus();
int wndholder_isAutoAvailable();
enum {
WNDHOLDER_ONINSERTWINDOW=50,
WNDHOLDER_ONREMOVEWINDOW=100,
WNDHOLDER_WANTGUID=150,
WNDHOLDER_WANTGROUP=200,
WNDHOLDER_GETROOTWNDPTR=250,
WNDHOLDER_GETCURGUID=300,
WNDHOLDER_GETCURGROUPID=350,
WNDHOLDER_GETCURROOTWND=400,
WNDHOLDER_GETCURID=450,
WNDHOLDER_ISGENERICGUID=500,
WNDHOLDER_ISGENERICGROUP=550,
WNDHOLDER_GETPREFERENCES=600,
WNDHOLDER_ONNEEDRELOADGRP=650,
WNDHOLDER_CANCELDEFERREDREMOVE=660,
WNDHOLDER_WANTAUTOFOCUS=670,
WNDHOLDER_ISAUTOAVAILABLE=680,
};
};
inline ifc_window *WindowHolder::onInsertWindow(GUID g, const wchar_t *groupid) {
return _call(WNDHOLDER_ONINSERTWINDOW, (ifc_window *)NULL, g, groupid);
}
inline void WindowHolder::onRemoveWindow(int def) {
_voidcall(WNDHOLDER_ONREMOVEWINDOW, def);
}
inline int WindowHolder::wantGuid(GUID g) {
return _call(WNDHOLDER_WANTGUID, 0, g);
}
inline int WindowHolder::wantGroup(const wchar_t *groupid) {
return _call(WNDHOLDER_WANTGROUP, 0, groupid);
}
inline ifc_window *WindowHolder::getRootWndPtr() {
return _call(WNDHOLDER_GETROOTWNDPTR, (ifc_window *)NULL);
}
inline GUID WindowHolder::getCurGuid() {
return _call(WNDHOLDER_GETCURGUID, INVALID_GUID);
}
inline const wchar_t *WindowHolder::getCurGroupId() {
return _call(WNDHOLDER_GETCURGROUPID, (const wchar_t *)NULL);
}
inline ifc_window *WindowHolder::getCurRootWnd() {
return _call(WNDHOLDER_GETCURROOTWND, (ifc_window *)NULL);
}
inline const wchar_t *WindowHolder::getCurId() {
return _call(WNDHOLDER_GETCURID, (const wchar_t *)NULL);
}
inline int WindowHolder::acceptsGenericGuid() {
return _call(WNDHOLDER_ISGENERICGUID, 0);
}
inline int WindowHolder::acceptsGenericGroup() {
return _call(WNDHOLDER_ISGENERICGROUP, 0);
}
inline int WindowHolder::wndholder_getPreferences(int what) {
return _call(WNDHOLDER_GETPREFERENCES, 0, what);
}
inline void WindowHolder::wndholder_onNeedReloadGroup(const wchar_t *id) {
_voidcall(WNDHOLDER_ONNEEDRELOADGRP, id);
}
inline void WindowHolder::cancelDeferredRemove() {
_voidcall(WNDHOLDER_CANCELDEFERREDREMOVE);
}
inline int WindowHolder::wndholder_wantAutoFocus() {
return _call(WNDHOLDER_WANTAUTOFOCUS, 1);
}
inline int WindowHolder::wndholder_isAutoAvailable() {
return _call(WNDHOLDER_ISAUTOAVAILABLE, 1);
}
class DeferredRemove;
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class WindowHolderI : public WindowHolder {
public:
WindowHolderI();
virtual ~WindowHolderI();
virtual ifc_window *onInsertWindow(GUID g, const wchar_t *groupid);
virtual void onRemoveWindow(int deferred);
void addAcceptGuid(GUID g);
void addAcceptGroup(const wchar_t *groupid);
void setAcceptAllGuids(int tf);
void setAcceptAllGroups(int tf);
virtual int acceptsGenericGroup() { return generic_group; }
virtual int acceptsGenericGuid() { return generic_guid; }
virtual int wantGuid(GUID g);
virtual int wantGroup(const wchar_t *groupid);
virtual void onInsert(ifc_window *w, const wchar_t *id) {};
virtual void onRemove(ifc_window *w, const wchar_t *id) {};
virtual ifc_window *getRootWndPtr()=0;
virtual GUID getCurGuid() { return cur_guid; }
virtual const wchar_t *getCurGroupId() { return cur_groupid; }
virtual ifc_window *getCurRootWnd() { return wnd; }
virtual GUID *getFirstAcceptedGuid();
virtual const wchar_t *getFirstAcceptedGroup();
virtual const wchar_t *getCurId() { return cur_id; }
virtual void cancelDeferredRemove();
virtual int wndholder_isAutoAvailable() { return 1; }
GUID getDeferedGuid() { return defered_guid; }
virtual int wndholder_getPreferences(int what)=0;
virtual void wndholder_onNeedReloadGroup(const wchar_t *id);
private:
ifc_window *createWindow(const GUID *g, const wchar_t *groupid);
virtual int wndholder_wantAutoFocus();
void destroyWindow();
ifc_window *wnd;
GUID cur_guid;
StringW cur_groupid;
StringW cur_id;
PtrList<GUID> accepted_guids;
PtrList<StringW> accepted_groups;
int generic_guid;
int generic_group;
svc_windowCreate *wc_svc;
GUID defered_guid;
DeferredRemove *dr;
protected:
RECVS_DISPATCH;
};
/**
Class
@short
@author Nullsoft
@ver 1.0
@see
*/
class WindowHolderWnd : public WINDOWHOLDER_PARENT, public WindowHolderI
{
public:
WindowHolderWnd();
virtual ~WindowHolderWnd();
virtual int onInit();
virtual ifc_window *getRootWndPtr() { return this; }
virtual void onInsert(ifc_window *w, const wchar_t *id);
virtual void onRemove(ifc_window *w, const wchar_t *id);
virtual int onResize();
virtual int handleRatio();
virtual int handleDesktopAlpha();
virtual int handleTransparency();
virtual int wndholder_getPreferences(int what) { return getPreferences(what); }
virtual int getPreferences(int what);
void setAutoOpen(int tf) { autoopen = tf; }
void setAutoClose(int tf) { autoclose = tf; }
void setNoCmdBar(int tf) { nocmdbar = tf; if (isInited()) invalidate(); }
void setNoAnim(int tf) { noanim = tf; }
virtual int onGroupChange(const wchar_t *grpid);
virtual int wndholder_wantAutoFocus();
void setAutoFocus(int autof) { autofocus = autof; }
void setAutoAvailable(int autoa) { autoavail = autoa; }
virtual int wndholder_isAutoAvailable() { return autoavail; }
private:
void notifyOnRemove(); // no virtual please
void notifyOnInsert(); // no virtual please
virtual void onSetVisible(int show);
virtual int onDeferredCallback(intptr_t p1, intptr_t p2);
int autoopen;
int autoclose;
int nocmdbar;
int noanim;
int has_wnd;
int autofocus;
int autoavail;
};
class DeferredRemove : public TimerClientDI
{
public:
DeferredRemove(WindowHolderI *parent) : whi(parent) {}
virtual ~DeferredRemove() {}
void post() {
timerclient_postDeferredCallback(1, 0);
}
virtual int timerclient_onDeferredCallback(intptr_t p1, intptr_t p2) {
if (p1 == 1 && whi != NULL) whi->onRemoveWindow(0);
else return TimerClientDI::timerclient_onDeferredCallback(p1, p2);
return 0;
}
private:
WindowHolderI *whi;
};
#endif