It is currently Mon Aug 20, 2018 9:48 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Skinnable Window (buttons, draggable, resizable)
PostPosted: Thu Feb 09, 2017 2:38 am 
Offline
Addict
Addict
User avatar

Joined: Mon May 26, 2003 3:07 pm
Posts: 1469
Location: Nantes
Based on post : viewtopic.php?f=13&t=66672
Coded in PB5.60+

Code:

DeclareModule SkinnableWindow
   Global NewMap SkinColors.i()
   Global NewMap SkinSizes.i()
   
   Declare InitSkin()
   Declare SkinWindow(Window, IsResizable=#True)
EndDeclareModule

Module SkinnableWindow
   EnableExplicit
   Prototype DrawCustomSkin(*skinData)
   Structure SKIN_ITEM
      name$
      parentBorder.i
      hit.q
      ;relative position for drawing
      top.f
      left.f
      right.f
      bottom.f
      ;absolute position for hit detection
      absTop.f
      absLeft.f
      absRight.f
      absBottom.f
   EndStructure
   Structure SKIN_DATA
      window.i
      isResizable.b
      isActive.b
      ;border gadgets
      activeBorder.i
      upBorder.i
      downBorder.i
      leftBorder.i
      rightBorder.i
      ;hit detection
      currentHit.q
      previousHit.q
      ;capture handler
      captureHit.q
      captX.i
      captY.i
      ;drawing
      drawCustomBorders.DrawCustomSkin
      drawCustomBorderItems.DrawCustomSkin
      List items.SKIN_ITEM()
   EndStructure   
   Global NewList SkinItems.SKIN_ITEM()
   Global NewMap SkinData.SKIN_DATA()
   
   EnumerationBinary
      #UP_BORDER
      #DOWN_BORDER
      #LEFT_BORDER
      #RIGHT_BORDER
      #CAPTION_BAR
      #CAPTION_TITLE
      #CAPTION_ICON
      #BUTTON_CLOSE
      #BUTTON_MIN
      #BUTTON_MAX
      ;combined flags for checking hit
      #ANY_BORDERS=#UP_BORDER | #DOWN_BORDER | #LEFT_BORDER | #RIGHT_BORDER
      #ANY_CAPTION=#CAPTION_BAR | #CAPTION_ICON | #CAPTION_TITLE
   EndEnumeration
   Procedure AddBorderItem(border$, name$, top.f, left.f, right.f, bottom.f, customHit=0)
      ResetList(SkinItems())
      Protected *skinZone.SKIN_ITEM=InsertElement(SkinItems())
      With *skinZone
         \name$=name$
         Select LCase(name$)
            Case "caption"
               \hit=#CAPTION_BAR
            Case "title"
               \hit=#CAPTION_TITLE
            Case "icon"
               \hit=#CAPTION_ICON
            Case "close"
               \hit=#BUTTON_CLOSE
            Case "max"
               \hit=#BUTTON_MAX
            Case "min"
               \hit=#BUTTON_MIN
            Default
               \hit=customHit
         EndSelect
         Select LCase(border$)
            Case "up"
               \parentBorder=#UP_BORDER
            Case "down"
               \parentBorder=#DOWN_BORDER
            Case "left"
               \parentBorder=#LEFT_BORDER
            Case "right"
               \parentBorder=#RIGHT_BORDER
            Default
               DebuggerError("border$ accepts one of following values: up, down, left, right")
         EndSelect
         \top=top
         \left=left
         \right=right
         \bottom=bottom
      EndWith
   EndProcedure
   
   Procedure DrawBorderItems(*skinData.SKIN_DATA)     
      With *skinData
         Protected x, y, w, h, cBox, cIcon
         Protected BorderSize=SkinSizes("border"), CornerSize=SkinSizes("corner"), CaptionSize=SkinSizes("caption")
         
         StartVectorDrawing(CanvasVectorOutput(\upBorder))         
         ;close
         If \currentHit & #BUTTON_CLOSE
            cBox=SkinColors("button_close")
            cIcon=SkinColors("stroke_hover")
         ElseIf \isActive
            cBox=SkinColors("button")
            cIcon=SkinColors("stroke")
         Else
            cBox=SkinColors("button_inactive")
            cIcon=SkinColors("stroke_inactive")
         EndIf
         w=45 : h=CaptionSize : x=GadgetWidth(\upBorder)-BorderSize-w : y=0
         ResetCoordinates()
         TranslateCoordinates(x, y)
         AddPathBox(0, 0, w, h)         
         VectorSourceColor(cBox)
         FillPath()
         VectorSourceColor(cIcon)
         MovePathCursor(w / 2-5, h / 2 - 5)
         AddPathLine(w / 2 + 4, h / 2 + 4)
         StrokePath(1)
         MovePathCursor(w / 2-5, h / 2 + 4)
         AddPathLine(w / 2 + 4, h / 2-5)
         StrokePath(1)
         ;maximize
         If \currentHit & #BUTTON_MAX
            cBox=SkinColors("button_hover")
            cIcon=SkinColors("stroke_hover")
         ElseIf \isActive
            cBox=SkinColors("button")
            cIcon=SkinColors("stroke")
         Else
            cBox=SkinColors("button_inactive")
            cIcon=SkinColors("stroke_inactive")
         EndIf
         ResetCoordinates()
         TranslateCoordinates(x-w, y)
         AddPathBox(0, 0, w, h)         
         VectorSourceColor(cBox)
         FillPath()
         VectorSourceColor(cIcon)
         AddPathBox(w / 2-5, h / 2-5, 10, 10)
         StrokePath(1)
         ;minimize
         If \currentHit & #BUTTON_MIN
            cBox=SkinColors("button_hover")
            cIcon=SkinColors("stroke_hover")
         ElseIf \isActive
            cBox=SkinColors("button")
            cIcon=SkinColors("stroke")
         Else
            cBox=SkinColors("button_inactive")
            cIcon=SkinColors("stroke_inactive")
         EndIf
         ResetCoordinates()
         TranslateCoordinates(x-w*2, y)
         AddPathBox(0, 0, w, h)
         VectorSourceColor(cBox)
         FillPath()
         VectorSourceColor(cIcon)
         MovePathCursor(w / 2-5, h / 2)
         AddPathLine(w / 2 + 4, h / 2)
         StrokePath(1)
         StopVectorDrawing()
      EndWith
   EndProcedure
   
   Procedure DrawBorders(*skinData.SKIN_DATA)
      With *skinData
         If \DrawCustomBorders
            \DrawCustomBorders(*skinData)
         Else
            ; Draw 4 borders
            If \isActive : Protected BorderColor=SkinColors("border") : Else : BorderColor=SkinColors("border_inactive") : EndIf
            StartDrawing(CanvasOutput(\upBorder))
            Box(0, 0, OutputWidth(), OutputHeight(), BorderColor)
            StopDrawing()           
            StartDrawing(CanvasOutput(\leftBorder))
            Box(0, 0, OutputWidth(), OutputHeight(), BorderColor)
            StopDrawing()
            StartDrawing(CanvasOutput(\downBorder))
            Box(0, 0, OutputWidth(), OutputHeight(), BorderColor)
            StopDrawing()
            StartDrawing(CanvasOutput(\rightBorder))
            Box(0, 0, OutputWidth(), OutputHeight(), BorderColor)
            StopDrawing()
         EndIf
         If \DrawCustomBorderItems
            \DrawCustomBorderItems(*skinData)
         Else
            ; Draw border items
            DrawBorderItems(*skinData.SKIN_DATA)
         EndIf         
      EndWith     
   EndProcedure
   
   Procedure DrawShadow(*skinData.SKIN_DATA, IsEnabled=#True, TransparencyColor=#Cyan)
      CompilerIf #PB_Compiler_OS=#PB_OS_Windows
         Static *dwmapi
         Static *DwmExtendFrameIntoClientArea
         Static *DwmSetWindowAttribute
         Protected hWnd=WindowID(*skinData\window)
         
         If Not *dwmapi
            *dwmapi=GetModuleHandle_("dwmapi")
            If *dwmapi And Not *DwmExtendFrameIntoClientArea And Not *DwmSetWindowAttribute
               *DwmExtendFrameIntoClientArea=GetProcAddress_(*dwmapi, Ascii("DwmExtendFrameIntoClientArea"))
               *DwmSetWindowAttribute=GetProcAddress_(*dwmapi, Ascii("DwmSetWindowAttribute"))
            EndIf
         EndIf
         
         If *DwmExtendFrameIntoClientArea And *DwmSetWindowAttribute
            CompilerIf Not Defined(DWMWA_NCRENDERING_POLICY, #PB_Constant) : #DWMWA_NCRENDERING_POLICY=2 : CompilerEndIf
            CompilerIf Not Defined(DWMNCRP_ENABLED, #PB_Constant) : #DWMNCRP_ENABLED=2 : CompilerEndIf
           
            If IsEnabled
               ;transform into opaque layered window
               SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, GetWindowLongPtr_(hWnd, #GWL_EXSTYLE) | #WS_EX_LAYERED)
               SetLayeredWindowAttributes_(hWnd, TransparencyColor, 255, #LWA_COLORKEY)
            Else
               SetWindowLongPtr_(hWnd, #GWL_EXSTYLE, GetWindowLongPtr_(hWnd, #GWL_EXSTYLE) & ~#WS_EX_LAYERED)
            EndIf
           
            ;enable drop shadow
            Protected *Margins=AllocateMemory(4*SizeOf(Long))
            FillMemory(*Margins, 4*SizeOf(Long), IsEnabled, #PB_Long)
            Protected value.Integer\i=#DWMNCRP_ENABLED
            CallFunctionFast(*DwmSetWindowAttribute, hWnd, #DWMWA_NCRENDERING_POLICY, value, SizeOf(value))
            CallFunctionFast(*DwmExtendFrameIntoClientArea, hWnd, *Margins)
         EndIf
         ProcedureReturn -1
      CompilerEndIf
   EndProcedure
   
   Procedure ResizeBorderItems(*skinData.SKIN_DATA)
      With *skinData
         Protected win=\window, parentBorder
         ClearList(\items())
         ForEach SkinItems()
            Select SkinItems()\parentBorder
               Case #UP_BORDER : parentBorder=\upBorder
               Case #DOWN_BORDER : parentBorder=\downBorder
               Case #LEFT_BORDER : parentBorder=\leftBorder
               Case #RIGHT_BORDER : parentBorder=\rightBorder
            EndSelect
         Protected top=SkinItems()\top + Bool(Sign(SkinItems()\top)<0) * GadgetHeight(parentBorder)
         Protected left=SkinItems()\left + Bool(Sign(SkinItems()\left)<0) *GadgetWidth(parentBorder)
         Protected right=SkinItems()\right + Bool(Sign(SkinItems()\right)<0) *GadgetWidth(parentBorder)
         Protected bottom=SkinItems()\bottom + Bool(Sign(SkinItems()\bottom)<0) * GadgetHeight(parentBorder)
            AddElement(\items())
            \items()=SkinItems()
            \items()\parentBorder=parentBorder
            \items()\top=top
            \items()\left=left
            \items()\right=right
            \items()\bottom=bottom
            \items()\absTop=top + GadgetY(parentBorder)
            \items()\absLeft=left + GadgetX(parentBorder)
            \items()\absRight=right + GadgetX(parentBorder)
            \items()\absBottom=bottom + GadgetY(parentBorder)
         Next
      EndWith
   EndProcedure
   
   Procedure ResizeBorders(*skinData.SKIN_DATA)
      With *skinData
         Protected win=\window
         Protected BorderSize=SkinSizes("border"), CornerSize=SkinSizes("corner"), CaptionSize=SkinSizes("caption")
         ;resize border gadgets
         ResizeGadget(\upBorder, 0, 0, WindowWidth(win), CaptionSize)
         ResizeGadget(\leftBorder, 0, CaptionSize, BorderSize, WindowHeight(win) - BorderSize - CaptionSize)
         ResizeGadget(\rightBorder, WindowWidth(win) - BorderSize, CaptionSize, BorderSize, WindowHeight(win) - BorderSize - CaptionSize)
         ResizeGadget(\downBorder, 0, WindowHeight(win) - BorderSize, WindowWidth(win), BorderSize)
         ;calculate position of border items
         ResizeBorderItems(*skinData.SKIN_DATA)
      EndWith     
   EndProcedure
   
   Procedure.i HitBorders(*skinData.SKIN_DATA)
      With *skinData
         Protected win=\window
         Protected gadget=\activeBorder
         Protected mouseX=WindowMouseX(win)
         Protected mouseY=WindowMouseY(win)
         Protected BorderSize=SkinSizes("border"), CornerSize=SkinSizes("corner"), CaptionSize=SkinSizes("caption")
         \currentHit=0
         ; Detect borders
         If \isResizable
            If (mouseX>-1 And mouseX<CornerSize)
               \currentHit | #LEFT_BORDER
            EndIf
            If (mouseY>-1 And mouseY<CornerSize)
               \currentHit | #UP_BORDER
            EndIf
            If (mouseX>=WindowWidth(win) - CornerSize)
               \currentHit | #RIGHT_BORDER
            EndIf
            If (mouseY>=WindowHeight(win) - CornerSize)
               \currentHit | #DOWN_BORDER
            EndIf
         EndIf         
         ; Change cursor
         Select \currentHit
            Case 0
               SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Default)
            Case #UP_BORDER, #DOWN_BORDER
               SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_UpDown)
            Case #LEFT_BORDER, #RIGHT_BORDER
               SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftRight)
               CompilerIf #PB_Compiler_OS=#PB_OS_Windows
               Case #LEFT_BORDER | #UP_BORDER, #RIGHT_BORDER | #DOWN_BORDER
                  SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftUpRightDown)
               Case #LEFT_BORDER | #DOWN_BORDER, #RIGHT_BORDER | #UP_BORDER
                  SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_LeftDownRightUp)
               CompilerElse
               Default
                  SetGadgetAttribute(gadget, #PB_Canvas_Cursor, #PB_Cursor_Cross)
               CompilerEndIf
         EndSelect
         ; Detect zones
         ForEach \items()
            If mouseX>=\items()\absLeft And mouseX<=\items()\absRight And mouseY>=\items()\absTop And mouseY<=\items()\absBottom
               \currentHit | \items()\hit
               Break
            EndIf
         Next
         ProcedureReturn \currentHit
      EndWith
   EndProcedure
   
   Procedure SkinEvents()
      Static rect.RECT
      Protected event=Event()
      Protected eventType=EventType()
      Protected gadget=EventGadget()
      Protected win=EventWindow()
      Protected *skinData.SKIN_DATA=SkinData("" + win)
      With *skinData     
         If event=#PB_Event_ActivateWindow
            \isActive=#True
            DrawBorders(*skinData)
         ElseIf event=#PB_Event_DeactivateWindow
            \isActive=#False
            DrawBorders(*skinData)
         ElseIf event=#PB_Event_Gadget
            \activeBorder=gadget
            Select eventType
               Case #PB_EventType_MouseEnter, #PB_EventType_MouseLeave
                  HitBorders(*skinData)
                  DrawBorders(*skinData)
               Case #PB_EventType_LeftButtonUp
                  If \captureHit
                     \captureHit=0
                     DrawShadow(*skinData, 1)
                  EndIf
               Case #PB_EventType_LeftButtonDown
                  If HitBorders(*skinData)
                     \captureHit=\currentHit
                     \captX=WindowMouseX(win)
                     \captY=WindowMouseY(win)
                     rect\left=WindowX(win)
                     rect\top=WindowY(win)
                     rect\right=rect\left + WindowWidth(win)
                     rect\bottom=rect\top + WindowHeight(win)
                  EndIf                 
               Case #PB_EventType_MouseMove
                  If GetGadgetAttribute(gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
                     If \captureHit & #ANY_BORDERS
                        Protected x=#PB_Ignore, y=#PB_Ignore, w=#PB_Ignore, h=#PB_Ignore
                        If \captureHit & #LEFT_BORDER
                           rect\left=DesktopMouseX() - \captX : w=rect\right-rect\left
                           x=rect\left
                        EndIf
                        If \captureHit & #RIGHT_BORDER
                           w=(rect\right - rect\left) + (DesktopMouseX() - \captX-rect\left)
                        EndIf
                        If \captureHit & #UP_BORDER
                           rect\top=DesktopMouseY() - \captY : h=rect\bottom-rect\top
                           y=rect\top
                        EndIf
                        If \captureHit & #DOWN_BORDER
                           h=(rect\bottom-rect\top) + (DesktopMouseY() - \captY-rect\top)
                        EndIf
                        DrawShadow(*skinData, 0)
                        ResizeWindow(win, x, y, w, h)
                        ResizeBorders(*skinData)
                        DrawBorders(*skinData)
                        ProcedureReturn
                     ElseIf \captureHit & #ANY_CAPTION
                        ResizeWindow(win, DesktopMouseX() - \captX, DesktopMouseY() - \captY, #PB_Ignore, #PB_Ignore)
                        ProcedureReturn
                     EndIf
                  EndIf
                  HitBorders(*skinData)
                  If \currentHit<>\previousHit
                     \previousHit=\currentHit
                     DrawBorders(*skinData)
                  EndIf
            EndSelect
         EndIf
      EndWith
   EndProcedure
   
   Procedure InitSkin()
      ; default colors
      SkinColors("background")=$7C7C7C
      SkinColors("border")=$6C6C6C
      SkinColors("border_inactive")=$6C6C6C
      SkinColors("button_close")=RGBA(230, 0, 0, 255)
      SkinColors("button")=RGBA(0, 0, 0, 0)
      SkinColors("button_inactive")=RGBA(0, 0, 0, 0)
      SkinColors("button_hover")=RGBA(0, 0, 0, 30)
      SkinColors("button_click")=RGBA(0, 0, 0, 50)
      SkinColors("stroke")=RGBA(0, 0, 0, 255)
      SkinColors("stroke_inactive")=RGBA(0, 0, 0, 100)
      SkinColors("stroke_hover")=RGBA(255, 255, 255, 255)
      SkinColors("stroke_click")=RGBA(255, 255, 255, 255)
      ; default sizes
      SkinSizes("border")=10
      SkinSizes("corner")=8
      SkinSizes("caption")=30
      ; default border items
      Protected BorderSize=SkinSizes("border"), CornerSize=SkinSizes("corner"), CaptionSize=SkinSizes("caption")
      AddBorderItem("up", "caption", 0, BorderSize, -BorderSize-1, CaptionSize-1)
      AddBorderItem("up", "title", 0, BorderSize, -45*3-BorderSize-5, CaptionSize-1)
      AddBorderItem("up", "close", 0, -45-BorderSize, -BorderSize-1, CaptionSize-1)
      AddBorderItem("up", "max", 0, -45*2-BorderSize, -45-BorderSize-1, CaptionSize-1)
      AddBorderItem("up", "min", 0, -45*3-BorderSize, -45*2-BorderSize-1, CaptionSize-1)
   EndProcedure
   
   Procedure SkinWindow(Window, IsResizable=#True)
      AddMapElement(SkinData(), "" + Window)
      With SkinData()
         \window=Window
         \isResizable=IsResizable
         \isActive=#True
         ; Skin borders
         \upBorder=CanvasGadget(#PB_Any, 0, 0, 0, 0)
         \leftBorder=CanvasGadget(#PB_Any, 0, 0, 0, 0)
         \rightBorder=CanvasGadget(#PB_Any, 0, 0, 0, 0)
         \downBorder=CanvasGadget(#PB_Any, 0, 0, 0, 0)
         ResizeBorders(SkinData())
         ; Skin events
         BindEvent(#PB_Event_ActivateWindow, @SkinEvents(), Window)
         BindEvent(#PB_Event_DeactivateWindow, @SkinEvents(), Window)
         BindEvent(#PB_Event_Gadget, @SkinEvents(), Window, \upBorder)
         BindEvent(#PB_Event_Gadget, @SkinEvents(), Window, \downBorder)
         BindEvent(#PB_Event_Gadget, @SkinEvents(), Window, \leftBorder)
         BindEvent(#PB_Event_Gadget, @SkinEvents(), Window, \rightBorder)
         ; Skin drawing (background, borders and shadow)
         SetWindowColor(Window, SkinColors("background"))
         DrawBorders(SkinData())
         DrawShadow(SkinData())
      EndWith
   EndProcedure
EndModule


CompilerIf #PB_Compiler_IsMainFile
   ; ********************
   ; EXAMPLE
   ; ********************
   UseModule SkinnableWindow
   
   InitSkin()
   If OpenWindow(10, 600, 600, 320, 240, "Borderless Window", #PB_Window_BorderLess)     
      SkinWindow(10, #True)
      ButtonGadget(100, 20, 50, 50, 20, "Exit")
      ButtonGadget(200, 80, 50, 50, 20, "Min")
     
      OpenWindow(11, 300, 300, 320, 240, "Borderless Window2", #PB_Window_BorderLess)
      SkinWindow(11, #True)
     
      Repeat
         Define event=WaitWindowEvent()
         If event=#PB_Event_Gadget
            Select EventGadget()
               Case 100
                  Break
                 
               Case 200
                  SetWindowState(10, #PB_Window_Minimize)
                 
            EndSelect
         EndIf
      Until event=#PB_Event_CloseWindow   
   EndIf
CompilerEndIf

_________________
Imagewin8.1 x64 5.31 | IDE | PB plugin | Tools | Sprite | JSON | visual tool


Last edited by eddy on Sun Feb 12, 2017 6:15 pm, edited 5 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Skinnable Window
PostPosted: Thu Feb 09, 2017 2:17 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4226
Location: Lyon - France
Really nice and modern window
Works very well, with no flickering on W7 X86 v5.60
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Skinnable Window
PostPosted: Fri Feb 10, 2017 6:29 am 
Offline
Addict
Addict
User avatar

Joined: Mon May 26, 2003 3:07 pm
Posts: 1469
Location: Nantes
Image

[updates
- display button
- detect if window is active or not

_________________
Imagewin8.1 x64 5.31 | IDE | PB plugin | Tools | Sprite | JSON | visual tool


Top
 Profile  
Reply with quote  
 Post subject: Re: Skinnable Window (buttons, draggable, resizable)
PostPosted: Tue Jun 12, 2018 8:18 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Apr 14, 2011 2:27 pm
Posts: 152
Hello
I have two questions :
1- How can I create a Title-Text for Skinnable window?
2. How can I define the event for window buttons? Like closing button and minimize.
Thanks.


Top
 Profile  
Reply with quote  
 Post subject: Re: Skinnable Window (buttons, draggable, resizable)
PostPosted: Wed Jun 13, 2018 7:07 am 
Offline
Addict
Addict
User avatar

Joined: Tue Oct 09, 2007 2:15 am
Posts: 987
Louise wrote:
Hello
I have two questions :
1- How can I create a Title-Text for Skinnable window?
2. How can I define the event for window buttons? Like closing button and minimize.
Thanks.


2. :
The procedure "SkinEvents()" ... add the following at the end of the "Case #PB_EventType_LeftButtonDown" section.

Code:
                   If \currentHit&#BUTTON_CLOSE
                     PostEvent(#PB_Event_CloseWindow, \window, \window) 
                   ElseIf \currentHit&#BUTTON_MAX
                     PostEvent(#PB_Event_MaximizeWindow, \window, \window) 
                   ElseIf \currentHit&#BUTTON_MIN
                     PostEvent(#PB_Event_MinimizeWindow, \window, \window) 
                   EndIf

and don't forget the event loop....here in eddy's demo code :
Code:
If event = #PB_Event_MinimizeWindow
  SetWindowState(EventWindow(), #PB_Window_Minimize) 
EndIf


1 :
See at the code, where the Canvas is drawn... there you have to do "DrawText" or "DrawVectorText"
depended on the drawing mode....

_________________
PureBasic 5.46 LTS / 5.62 (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce GTX 980 X4 Ultra | HAF XF Evo​​
English is not my native language... (I often use DeepL to translate my texts.)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye