Jump to content

Recommended Posts

  • Premium

Emoji in textline broken ?

emoji_broken.gif?width=398&height=465

Fixed ?

 emoji_fixed.gif?width=398&height=465

 


This is the hidden content, please

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Metin2 Dev 113
  • Eyes 1
  • Good 9
  • Love 3
  • Love 45
  • 3 months later...
  • Active+ Member

I am using the experimental version of this system together with your __BL_ENABLE_PICKUP_ITEM_EFFECT__ system. In PythonSlotWindow.cpp, 

This part:
 

		if (m_pSlotActiveEffect)
			m_pSlotActiveEffect->SetClippingMaskRect(m_rMaskRect);

Is not compatible with your __BL_ENABLE_PICKUP_ITEM_EFFECT__ system and it doesn't let client build. Because of this in PythonSlotWindow.h:

 

#if defined(__BL_ENABLE_PICKUP_ITEM_EFFECT__)
			CAniImageBox* m_pSlotActiveEffect[SLOT_ACTIVE_EFFECT_COUNT];
#else
			CAniImageBox* m_pSlotActiveEffect;
#endif


So copying from another if statement from your __BL_ENABLE_PICKUP_ITEM_EFFECT__  system, I edited the first code as such:

 

#if defined(__BL_ENABLE_PICKUP_ITEM_EFFECT__)
		for (int i = 0; i < SLOT_ACTIVE_EFFECT_COUNT; i++)
		{
			if (m_pSlotActiveEffect[i])
				m_pSlotActiveEffect[i]->SetClippingMaskRect(m_rMaskRect);
		}
#else
		if (m_pSlotActiveEffect)
			m_pSlotActiveEffect->SetClippingMaskRect(m_rMaskRect);
#endif


I could compile the Client after this. Did I mess something up or does this make sense? 

Edited by Debloat
  • Metin2 Dev 1
  • 2 months later...
  • Active+ Member

Can someone show me an example usage?
How should we adapt it to other windows?
For example, the task list.(in character window -> quest)

On 12/28/2022 at 2:19 PM, filipw1 said:

scrollowanie_masne_fest.gif

To get smooth scrolling like this in music, guild symbol selection (and maybe some custom systems you already have idk), just replace ListBoxEx class.

  Reveal hidden contents

https://pastebin.com/MwRS82jG

 

class ListBoxEx(Window):
    class Item(Window):
        def __init__(self):
            Window.__init__(self)
 
        def __del__(self):
            Window.__del__(self)
 
        def SetParent(self, parent):
            Window.SetParent(self, parent)
            self.parent = proxy(parent)
 
        def OnMouseLeftButtonDown(self):
            self.parent.SelectItem(self)
 
        def OnRender(self):
            if self.parent.GetSelectedItem() == self:
                self.OnSelectedRender()
 
        def OnSelectedRender(self):
            x, y = self.GetGlobalPosition()
            grp.SetColor(grp.GenerateColor(0.0, 0.0, 0.7, 0.7))
            grp.RenderBar(x, y, self.GetWidth(), self.GetHeight())
 
    def __init__(self):
        Window.__init__(self)
 
        self.viewItemCount = 10
        self.basePos = 0
        self.itemHeight = 16
        self.itemStep = 20
        self.selItem = 0
        self.itemList = []
        self.onSelectItemEvent = lambda *arg: None
 
        if localeInfo.IsARABIC():
            self.itemWidth = 130
        else:
            self.itemWidth = 100
 
        self.scrollBar = None
        self.__UpdateSize()
 
    def __del__(self):
        Window.__del__(self)
 
    def __UpdateSize(self):
        height = self.itemStep * self.__GetViewItemCount()
 
        self.SetSize(self.itemWidth, height)
 
    def IsEmpty(self):
        if len(self.itemList) == 0:
            return 1
        return 0
 
    def SetItemStep(self, itemStep):
        self.itemStep = itemStep
        self.__UpdateSize()
 
    def SetItemSize(self, itemWidth, itemHeight):
        self.itemWidth = itemWidth
        self.itemHeight = itemHeight
        self.__UpdateSize()
 
    def SetViewItemCount(self, viewItemCount):
        self.viewItemCount = viewItemCount
 
    def SetSelectEvent(self, event):
        self.onSelectItemEvent = event
 
    def SetBasePos(self, basePos):
        if app.__BL_CLIP_MASK__:
            self.basePos = basePos
 
            curbp = self.basePos
 
            itemheight = self.itemStep * len(self.itemList)
            myheight = self.GetHeight()
 
            if itemheight < myheight:
                curbp = 0
 
            fromPos = curbp
            curPos = 0
            toPos = curbp + self.GetHeight()
            for item in self.itemList:
                if curPos + self.itemStep < fromPos or curPos > toPos:
                    item.Hide()
                else:
                    item.Show()
 
                item.SetPosition(0, curPos - fromPos)
                curPos += self.itemStep
        else:
            for oldItem in self.itemList[self.basePos:self.basePos + self.viewItemCount]:
                oldItem.Hide()
 
            self.basePos = basePos
 
            pos = basePos
            for newItem in self.itemList[self.basePos:self.basePos + self.viewItemCount]:
                (x, y) = self.GetItemViewCoord(pos, newItem.GetWidth())
                newItem.SetPosition(x, y)
                newItem.Show()
                pos += 1
 
    def GetItemIndex(self, argItem):
        return self.itemList.index(argItem)
 
    def GetSelectedItem(self):
        return self.selItem
 
    def SelectIndex(self, index):
 
        if index >= len(self.itemList) or index < 0:
            self.selItem = None
            return
 
        try:
            self.selItem = self.itemList[index]
        except:
            pass
 
    def SelectItem(self, selItem):
        self.selItem = selItem
        self.onSelectItemEvent(selItem)
 
    def RemoveAllItems(self):
        for item in self.itemList:
            item.Hide()
 
        self.selItem = None
        self.itemList = []
 
        if self.scrollBar:
            self.scrollBar.SetPos(0)
 
    def RemoveItem(self, delItem):
        if delItem == self.selItem:
            self.selItem = None
 
        self.itemList.remove(delItem)
 
    def AppendItem(self, newItem):
        newItem.SetParent(self)
        newItem.SetSize(self.itemWidth, self.itemHeight)
 
        if app.__BL_CLIP_MASK__:
            newItem.SetClippingMaskWindow(self)
 
        pos = len(self.itemList)
        if self.__IsInViewRange(pos):
            (x, y) = self.GetItemViewCoord(pos, newItem.GetWidth())
            newItem.SetPosition(x, y)
            newItem.Show()
        else:
            newItem.Hide()
 
        self.itemList.append(newItem)
 
    def SetScrollBar(self, scrollBar):
        scrollBar.SetScrollEvent(__mem_func__(self.__OnScroll))
        self.scrollBar = scrollBar
 
    def __OnScroll(self):
        if app.__BL_CLIP_MASK__:
            self.SetBasePos(int(self.scrollBar.GetPos() * (self.__GetItemCount() - 1) * self.itemStep))
        else:
            self.SetBasePos(int(self.scrollBar.GetPos() * self.__GetScrollLen()))
 
    def __GetScrollLen(self):
        scrollLen = self.__GetItemCount() - self.__GetViewItemCount()
        if scrollLen < 0:
            return 0
 
        return scrollLen
 
    def __GetViewItemCount(self):
        return self.viewItemCount
 
    def __GetItemCount(self):
        return len(self.itemList)
 
    def GetItemViewCoord(self, pos, itemWidth):
        if localeInfo.IsARABIC():
            return (self.GetWidth() - itemWidth - 10, (pos - self.basePos) * self.itemStep)
        else:
            return (0, (pos - self.basePos) * self.itemStep)
 
    def __IsInViewRange(self, pos):
        if pos < self.basePos:
            return 0
        if pos >= self.basePos + self.viewItemCount:
            return 0
        return 1

 

Not working. As you show, the sliding process does not occur, there is visual distortion.

Edited by blaxis
  • Metin2 Dev 1
  • 2 months later...
On 12/16/2022 at 10:45 PM, masodikbela said:

Here is a little collab for the clipping, this extends the ExpandedImageBox, so you can scale/rotate those images and still be able to clip them. The code contains very informative comments so if you want to learn a few tricks you might want to read them.

  Reveal hidden contents

In GrpExpandedImageInstance.cpp replace the whole Render function with this:

void CGraphicExpandedImageInstance::OnRender(RECT* rMask)
{
	// Okay so first we are gonna rework the code to use transofrmation matrix.
	// To do that we just have to touch the xyzs. This means we have to setup
	// them to match the original rectangle (without scaling rotation translation).
	// Just like how we would want to render the image to the left top corner
	// of the screen as it is in the file.
	// 
	// We will obviously need the UVs so I'm not gonna touch that part, it has
	// nothing to do with the transformation matrix.
	//
	// The only thing is that the rotation and scaling is virtual so other codes 
	// will not see the rect of the scaled/rotated eximagebox correctly so if you 
	// want to put another image on such eximageboxes you will need extra logic,
	// perhabs the current structure for clipping will not be enough for that anyway.
	//
	// With the DEBUG_CLIPMASK macro you can highlight the parent window's rect.


	CGraphicImage* pImage = m_roImage.GetPointer();
	CGraphicTexture* pTexture = pImage->GetTexturePointer();

	const RECT& c_rRect = pImage->GetRectReference();
	float texReverseWidth = 1.0f / float(pTexture->GetWidth());
	float texReverseHeight = 1.0f / float(pTexture->GetHeight());
	float su = (c_rRect.left - m_RenderingRect.left) * texReverseWidth;
	float sv = (c_rRect.top - m_RenderingRect.top) * texReverseHeight;
	float eu = (c_rRect.left + m_RenderingRect.right + (c_rRect.right - c_rRect.left)) * texReverseWidth;
	float ev = (c_rRect.top + m_RenderingRect.bottom + (c_rRect.bottom - c_rRect.top)) * texReverseHeight;

	// set up the vertex position in screen coordinates
	// the rendering rect is usually 0, only used for stuff like hp bar, 
	// normal window base and so on, where you want to replicate the texture
	// multiple times (aka. wrap texture address mode). Since it will count
	// as the "part of the basic image box" we will add it here as well.
	//
	// The only trick we will apply that we will shift the wrapping to the 
	// end positions instead of substracting them from the start positions,
	// since we want to base the original box to 0,0. We will adjust it on
	// the translation.
	float sx = 0.f;
	float sy = 0.f;
	float ex = float(pImage->GetWidth()) + m_RenderingRect.right + m_RenderingRect.left;
	float ey = float(pImage->GetHeight()) + m_RenderingRect.bottom + m_RenderingRect.top;

	TPDTVertex vertices[4];
	vertices[0].position.x = sx;
	vertices[0].position.y = sy;
	vertices[0].position.z = 0.0f;
	vertices[0].texCoord = TTextureCoordinate(su, sv);
	vertices[0].diffuse = m_DiffuseColor;

	vertices[1].position.x = ex;
	vertices[1].position.y = sy;
	vertices[1].position.z = 0.0f;
	vertices[1].texCoord = TTextureCoordinate(eu, sv);
	vertices[1].diffuse = m_DiffuseColor;

	vertices[2].position.x = sx;
	vertices[2].position.y = ey;
	vertices[2].position.z = 0.0f;
	vertices[2].texCoord = TTextureCoordinate(su, ev);
	vertices[2].diffuse = m_DiffuseColor;

	vertices[3].position.x = ex;
	vertices[3].position.y = ey;
	vertices[3].position.z = 0.0f;
	vertices[3].texCoord = TTextureCoordinate(eu, ev);
	vertices[3].diffuse = m_DiffuseColor;

	// Now we are going to apply a transformation matrix that will
	// rotate/scale/transpose the vertices to the correct position.
	//
	// We can do it 2 different ways, either set up a world transform
	// so the GPU will do this for us for every vertex we stream to it,
	// or we can directly apply it here CPU side.
	// Since we have very few (4) vertices its better to do it here 
	// since changing device states comes with some overhead, so its 
	// better to do that only when its absolutely necessary or when
	// we can spare some cpu cycles by sending the work to the GPU.

	D3DXMATRIX transform, mTemp;
	D3DXMatrixScaling(&transform, m_v2Scale.x, m_v2Scale.y, 1.f);
	D3DXMatrixTranslation(&mTemp, -(ex - sx) / 2.f, -(ey - sy) / 2.f, 0.f);
	transform *= mTemp;
	D3DXMatrixRotationZ(&mTemp, D3DXToRadian(m_fRotation));
	transform *= mTemp;
	D3DXMatrixTranslation(&mTemp, (ex - sx) / 2.f, (ey - sy) / 2.f, 0.f);
	transform *= mTemp;
	D3DXMatrixTranslation(&mTemp, m_v2Position.x - m_RenderingRect.left, m_v2Position.y - m_RenderingRect.top, 0.f);
	transform *= mTemp;

	for (size_t i = 0; i < 4; ++i)
	{
		const D3DXVECTOR2 pos(vertices[i].position.x, vertices[i].position.y);
		D3DXVECTOR4 out;
		D3DXVec2Transform(&out, &pos, &transform);
		vertices[i].position.x = out.x - 0.5f;
		vertices[i].position.y = out.y - 0.5f;
	}

	switch (m_iRenderingMode)
	{
	case RENDERING_MODE_SCREEN:
	case RENDERING_MODE_COLOR_DODGE:
		STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR);
		STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
		break;
	case RENDERING_MODE_MODULATE:
		STATEMANAGER.SaveRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
		STATEMANAGER.SaveRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
		break;
	}

	// Since dx8 doesn't have clipping, we have to apply a bit of trickery here.
	// We are going to use stenciling. This requires to have space for stencil
	// information in the depth buffer, so you will need to ask the game to
	// create an appropriate depth buffer, by changing m_dwMinStencilBits to 1
	// in D3D_CDeviceInfo::FindDepthStencilFormat.
	// Stencil buffer will store a custom value on every position you render to
	// and you can later compare it when rendering something else to drop specific
	// pixels to achieve various effects.
	// With this method it is possible to later extend the functionality since 
	// you can basically clip any shape not just rectangle like with dx9 clipping.
	// This can be useful when your parent window is a rotated exImageBox and you
	// want to clip inside it.
	if (rMask)
	{
		// First of all we will draw a rectangle equal to the size of the parent
		// window's size. We don't need any texture pos or colour, so SPVertex
		// struct would be enough but I cba creating funcs for it so just go with
		// this one.

		TPDTVertex maskVertices[4];
		maskVertices[0].position.x = float(rMask->left) - 0.5f;
		maskVertices[0].position.y = float(rMask->top) - 0.5f;
		maskVertices[0].position.z = 0.0f;

		maskVertices[1].position.x = float(rMask->right) - 0.5f;
		maskVertices[1].position.y = float(rMask->top) - 0.5f;
		maskVertices[1].position.z = 0.0f;

		maskVertices[2].position.x = float(rMask->left) - 0.5f;
		maskVertices[2].position.y = float(rMask->bottom) - 0.5f;
		maskVertices[2].position.z = 0.0f;

		maskVertices[3].position.x = float(rMask->right) - 0.5f;
		maskVertices[3].position.y = float(rMask->bottom) - 0.5f;
		maskVertices[3].position.z = 0.0f;

		// Normally nothing else uses stencil in the base game, but we will have to
		// clear the other stuff we set up in previous renders.
		STATEMANAGER.GetDevice()->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0.f, 0);

		// Now enable stenciling, and make it to fail always (so this random rectangle
		// wont show up in our rendertarget).
		const DWORD zWrite = STATEMANAGER.GetRenderState(D3DRS_ZWRITEENABLE);
		STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
		STATEMANAGER.SaveRenderState(D3DRS_STENCILENABLE, TRUE);
#ifdef DEBUG_CLIPMASK
		maskVertices[0].diffuse = maskVertices[1].diffuse = maskVertices[2].diffuse = maskVertices[3].diffuse = 0x5F00FF00;
		STATEMANAGER.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
		STATEMANAGER.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
#else
		STATEMANAGER.SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
		STATEMANAGER.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_NEVER);
#endif
		STATEMANAGER.SetRenderState(D3DRS_STENCILREF, 1);

		// And now just render it just as a normal image.
		CGraphicBase::SetPDTStream(maskVertices, 4);
		CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT);

		STATEMANAGER.SetTexture(0, NULL);
		STATEMANAGER.SetTexture(1, NULL);
		STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
		STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2);

		// After the render set up the stencil to only succeed on pixels we wrote 1 to.
#ifdef DEBUG_CLIPMASK
		STATEMANAGER.SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
#else
		STATEMANAGER.SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
#endif
		STATEMANAGER.SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);

		STATEMANAGER.SetRenderState(D3DRS_ZWRITEENABLE, zWrite);
	}

	// set up min/magfilter for scaling, instantly restore mipfilter, we don't need mips
	DWORD minF, magF, mipF;
	STATEMANAGER.GetTextureStageState(0, D3DTSS_MINFILTER, &minF);
	STATEMANAGER.GetTextureStageState(0, D3DTSS_MAGFILTER, &magF);
	STATEMANAGER.GetTextureStageState(0, D3DTSS_MIPFILTER, &mipF);
	STATEMANAGER.SetBestFiltering(0);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_MIPFILTER, mipF);

	// 2004.11.18.myevan.ctrl+alt+del ąÝşą »çżë˝Ă ƨ±â´Â ą®Á¦ 	
	if (CGraphicBase::SetPDTStream(vertices, 4))
	{
		CGraphicBase::SetDefaultIndexBuffer(CGraphicBase::DEFAULT_IB_FILL_RECT);

		STATEMANAGER.SetTexture(0, pTexture->GetD3DTexture());
		STATEMANAGER.SetTexture(1, NULL);
		STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
		STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 4, 0, 2);
	}
	//STATEMANAGER.DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, c_FillRectIndices, D3DFMT_INDEX16, vertices, sizeof(TPDTVertex));
	/////////////////////////////////////////////////////////////

	// reset filters
	STATEMANAGER.SetTextureStageState(0, D3DTSS_MINFILTER, minF);
	STATEMANAGER.SetTextureStageState(0, D3DTSS_MAGFILTER, magF);

	// And finally disable stenciling again.
	if (rMask)
		STATEMANAGER.RestoreRenderState(D3DRS_STENCILENABLE);

	switch (m_iRenderingMode)
	{
	case RENDERING_MODE_SCREEN:
	case RENDERING_MODE_COLOR_DODGE:
	case RENDERING_MODE_MODULATE:
		STATEMANAGER.RestoreRenderState(D3DRS_SRCBLEND);
		STATEMANAGER.RestoreRenderState(D3DRS_DESTBLEND);
		break;
	}
}

In StateManager.h add this function as public to the CStateManager class:

LPDIRECT3DDEVICE8 GetDevice() { return m_lpD3DDev; }

And last in GrpDetector.cpp search for m_dwMinStencilBits and set it to 1.

 

hi can you modify dxd9?

  • 3 months later...
On 12/28/2022 at 7:19 AM, filipw1 said:

scrollowanie_masne_fest.gif

To get smooth scrolling like this in music, guild symbol selection (and maybe some custom systems you already have idk), just replace ListBoxEx class.

  Reveal hidden contents

https://pastebin.com/MwRS82jG

 

class ListBoxEx(Window):
    class Item(Window):
        def __init__(self):
            Window.__init__(self)
 
        def __del__(self):
            Window.__del__(self)
 
        def SetParent(self, parent):
            Window.SetParent(self, parent)
            self.parent = proxy(parent)
 
        def OnMouseLeftButtonDown(self):
            self.parent.SelectItem(self)
 
        def OnRender(self):
            if self.parent.GetSelectedItem() == self:
                self.OnSelectedRender()
 
        def OnSelectedRender(self):
            x, y = self.GetGlobalPosition()
            grp.SetColor(grp.GenerateColor(0.0, 0.0, 0.7, 0.7))
            grp.RenderBar(x, y, self.GetWidth(), self.GetHeight())
 
    def __init__(self):
        Window.__init__(self)
 
        self.viewItemCount = 10
        self.basePos = 0
        self.itemHeight = 16
        self.itemStep = 20
        self.selItem = 0
        self.itemList = []
        self.onSelectItemEvent = lambda *arg: None
 
        if localeInfo.IsARABIC():
            self.itemWidth = 130
        else:
            self.itemWidth = 100
 
        self.scrollBar = None
        self.__UpdateSize()
 
    def __del__(self):
        Window.__del__(self)
 
    def __UpdateSize(self):
        height = self.itemStep * self.__GetViewItemCount()
 
        self.SetSize(self.itemWidth, height)
 
    def IsEmpty(self):
        if len(self.itemList) == 0:
            return 1
        return 0
 
    def SetItemStep(self, itemStep):
        self.itemStep = itemStep
        self.__UpdateSize()
 
    def SetItemSize(self, itemWidth, itemHeight):
        self.itemWidth = itemWidth
        self.itemHeight = itemHeight
        self.__UpdateSize()
 
    def SetViewItemCount(self, viewItemCount):
        self.viewItemCount = viewItemCount
 
    def SetSelectEvent(self, event):
        self.onSelectItemEvent = event
 
    def SetBasePos(self, basePos):
        if app.__BL_CLIP_MASK__:
            self.basePos = basePos
 
            curbp = self.basePos
 
            itemheight = self.itemStep * len(self.itemList)
            myheight = self.GetHeight()
 
            if itemheight < myheight:
                curbp = 0
 
            fromPos = curbp
            curPos = 0
            toPos = curbp + self.GetHeight()
            for item in self.itemList:
                if curPos + self.itemStep < fromPos or curPos > toPos:
                    item.Hide()
                else:
                    item.Show()
 
                item.SetPosition(0, curPos - fromPos)
                curPos += self.itemStep
        else:
            for oldItem in self.itemList[self.basePos:self.basePos + self.viewItemCount]:
                oldItem.Hide()
 
            self.basePos = basePos
 
            pos = basePos
            for newItem in self.itemList[self.basePos:self.basePos + self.viewItemCount]:
                (x, y) = self.GetItemViewCoord(pos, newItem.GetWidth())
                newItem.SetPosition(x, y)
                newItem.Show()
                pos += 1
 
    def GetItemIndex(self, argItem):
        return self.itemList.index(argItem)
 
    def GetSelectedItem(self):
        return self.selItem
 
    def SelectIndex(self, index):
 
        if index >= len(self.itemList) or index < 0:
            self.selItem = None
            return
 
        try:
            self.selItem = self.itemList[index]
        except:
            pass
 
    def SelectItem(self, selItem):
        self.selItem = selItem
        self.onSelectItemEvent(selItem)
 
    def RemoveAllItems(self):
        for item in self.itemList:
            item.Hide()
 
        self.selItem = None
        self.itemList = []
 
        if self.scrollBar:
            self.scrollBar.SetPos(0)
 
    def RemoveItem(self, delItem):
        if delItem == self.selItem:
            self.selItem = None
 
        self.itemList.remove(delItem)
 
    def AppendItem(self, newItem):
        newItem.SetParent(self)
        newItem.SetSize(self.itemWidth, self.itemHeight)
 
        if app.__BL_CLIP_MASK__:
            newItem.SetClippingMaskWindow(self)
 
        pos = len(self.itemList)
        if self.__IsInViewRange(pos):
            (x, y) = self.GetItemViewCoord(pos, newItem.GetWidth())
            newItem.SetPosition(x, y)
            newItem.Show()
        else:
            newItem.Hide()
 
        self.itemList.append(newItem)
 
    def SetScrollBar(self, scrollBar):
        scrollBar.SetScrollEvent(__mem_func__(self.__OnScroll))
        self.scrollBar = scrollBar
 
    def __OnScroll(self):
        if app.__BL_CLIP_MASK__:
            self.SetBasePos(int(self.scrollBar.GetPos() * (self.__GetItemCount() - 1) * self.itemStep))
        else:
            self.SetBasePos(int(self.scrollBar.GetPos() * self.__GetScrollLen()))
 
    def __GetScrollLen(self):
        scrollLen = self.__GetItemCount() - self.__GetViewItemCount()
        if scrollLen < 0:
            return 0
 
        return scrollLen
 
    def __GetViewItemCount(self):
        return self.viewItemCount
 
    def __GetItemCount(self):
        return len(self.itemList)
 
    def GetItemViewCoord(self, pos, itemWidth):
        if localeInfo.IsARABIC():
            return (self.GetWidth() - itemWidth - 10, (pos - self.basePos) * self.itemStep)
        else:
            return (0, (pos - self.basePos) * self.itemStep)
 
    def __IsInViewRange(self, pos):
        if pos < self.basePos:
            return 0
        if pos >= self.basePos + self.viewItemCount:
            return 0
        return 1

 

spacer.png

a good way to work with the listbox, thanks for sharing 

great job, thanks for sharing @ Mali

Edited by Metin2 Dev International
Core X - External 2 Internal
  • Metin2 Dev 1
  • 4 weeks later...
  • 3 months later...
  • 1 year later...

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.