Initial community commit
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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(®);
|
||||
back_buffer->selectClipRgn(®);
|
||||
#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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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); }
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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(®);
|
||||
RegionI clip(&r);
|
||||
reg.offset(0, offset);
|
||||
clip.subtractRegion(®);
|
||||
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(®);
|
||||
RegionI clip(&r);
|
||||
reg.offset(0, offset);
|
||||
clip.subtractRegion(®);
|
||||
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(®);
|
||||
RegionI clip(&r);
|
||||
reg.offset(offset, 0);
|
||||
clip.subtractRegion(®);
|
||||
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(®);
|
||||
|
||||
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(®);
|
||||
RegionI clip(&r);
|
||||
reg.offset(offset, 0);
|
||||
clip.subtractRegion(®);
|
||||
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(®);
|
||||
|
||||
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(®);
|
||||
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(®);
|
||||
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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user