Code: Select all
; AZJIO (19.11.2023)
EnableExplicit
#Window = 0
;- Enumeration
Enumeration Gadget
#cnvPalette
#cnvScene
; #btnOpenLevel
#btnSave
#btnOpenImg
#btnClear
#Opt1
#Opt2
#Opt3
EndEnumeration
Declare hsb_to_rgb()
Declare rgb_to_hsb()
UseGIFImageDecoder()
UsePNGImageDecoder()
;- Global
Global tmp, i, j, y, x, Color, Type, ecnv, selectedColor, StyleBox
Global mxxOld, myyOld, pendown, delmode, mxx, myy
Global tmp$
Global ImagePlugin
Global Dim arr_rgb(2)
Global Dim arr_hsb(2)
Global w, h
Global ini$ = GetPathPart(ProgramFilename()) + "BallBrick.ini"
Global CELLSIZEW = 20
Global CELLSIZEH = 20
; #CELLSIZE
Global XXX = 24
Global YYY = 24
; Global Dim aIcon(XXX, YYY)
Global Dim aIcon(XXX, YYY)
Global AreaX = CELLSIZEW * XXX
Global AreaY = CELLSIZEH * YYY
Structure Bricks
x.i
y.i
t.i
c.i
EndStructure
;- GUI
OpenWindow(#Window, 0, 0, AreaX + 110, AreaY + 4, "IconEditor", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
; SetWindowColor(#Window, 0)
OptionGadget(#Opt1, AreaX + 11, AreaY - 230, 98, 20, "Solid")
OptionGadget(#Opt2, AreaX + 11, AreaY - 210, 98, 20, "Box")
OptionGadget(#Opt3, AreaX + 11, AreaY - 190, 98, 20, "Round")
SetGadgetState(#Opt2, 1)
StyleBox = 1
; ButtonGadget(#btnOpenLevel, AreaX + 6, AreaY - 160, 100, 33 , "Level")
ButtonGadget(#btnClear, AreaX + 6, AreaY - 120, 100, 33 , "Clear")
ButtonGadget(#btnOpenImg, AreaX + 6, AreaY - 80, 100, 33 , "Open img")
ButtonGadget(#btnSave, AreaX + 6, AreaY - 40, 100, 33 , "Save")
; холст Сцена
CanvasGadget(#cnvScene, 0, 0, AreaX + 4, AreaY + 4, #PB_Canvas_Border)
If StartDrawing(CanvasOutput(#cnvScene))
Box(0, 0, AreaX, AreaY, 0)
StopDrawing()
EndIf
; холст Палитра
CanvasGadget(#cnvPalette, AreaX + 4, 0, 106 , AreaY - 248)
If StartDrawing(CanvasOutput(#cnvPalette))
Box(0, 0, 110 , AreaY - 168 , $333333)
; Спектр
w = 100
h = 10
arr_hsb(1) = 100
arr_hsb(2) = 100
For i = 100 To 0 Step - 1
Line(93, 150 - i, 10, 1, RGB(i * 2.5, i * 2.5, i * 2.5))
Next
; For i=0 To 255
; Line(91, i, 10, 1, RGB(i, i, i))
; Next
For j = 0 To 90
arr_hsb(2) = 100 - j
For i = 0 To w
arr_hsb(0) = i * 360 / w
hsb_to_rgb()
Plot(j + 1, i + 50, RGB(arr_rgb(0), arr_rgb(1), arr_rgb(2)))
Next
Next
selectedColor = $7DC4DF
; Box(0, 0, 110, 30, selectedColor)
Box(27, 8, 32, 32, $FFFFFF)
Box(28, 9, 30, 30, selectedColor)
StopDrawing()
EndIf
;; init palette end
Procedure DrawPixel(selectedColor)
Protected myy, mxx
; преобразование в позицию квадратов x, y, чтобы сравнить являются ли квадраты на одной линии
mxx = Int(GetGadgetAttribute(#cnvScene, #PB_Canvas_MouseX) / CELLSIZEW) * CELLSIZEW
myy = Int(GetGadgetAttribute(#cnvScene, #PB_Canvas_MouseY) / CELLSIZEH) * CELLSIZEH
If StartDrawing(CanvasOutput(#cnvScene))
Select StyleBox
Case 0
Box(mxx, myy, CELLSIZEW, CELLSIZEH, selectedColor)
Case 1
Box(mxx, myy, CELLSIZEW - 1, CELLSIZEH - 1, selectedColor)
Case 2
RoundBox(mxx + 1, myy + 1, CELLSIZEW - 2, CELLSIZEH - 2, 2, 2, selectedColor)
EndSelect
StopDrawing()
EndIf
EndProcedure
;- Loop
Repeat
Select WaitWindowEvent():
Case #PB_Event_CloseWindow
CloseWindow(#Window)
End
; $00FF99
;- Loop_Gadget
Case #PB_Event_Gadget
Select EventGadget()
Case #Opt1
; SetGadgetState(#Opt1, 1)
StyleBox = 0
Case #Opt2
; SetGadgetState(#Opt2, 1)
StyleBox = 1
Case #Opt3
; SetGadgetState(#Opt3, 1)
StyleBox = 2
; Case #btnOpenLevel
; tmp$ = OpenFileRequester("Открыть уровень", GetCurrentDirectory(), "txt|*.txt", 0)
; If Asc(tmp$)
; EndIf
Case #btnClear
If StartDrawing(CanvasOutput(#cnvScene))
Box(0, 0, AreaX, AreaY, 0)
StopDrawing()
EndIf
Case #btnOpenImg
tmp$ = OpenFileRequester("Open file", GetCurrentDirectory(), "img|*.bmp;*.png;*.gif;*.ico", 0)
If Asc(tmp$)
#Image = 0
If LoadImage(#Image, tmp$)
If StartDrawing(CanvasOutput(#cnvScene))
If GetExtensionPart(tmp$) = "ico"
XXX = ImageWidth(#Image)
YYY = ImageHeight(#Image)
; Debug XXX
; Debug YYY
Box(0, 0, XXX + 1, YYY + 1, $010203) ; стираем холст цветом, который задан как прозрачный
Dim aIcon(XXX, YYY) ; пересоздаём массив, в отличии от ReDim Dim стирает данные, но они и не нужны.
CELLSIZEW = AreaX / XXX
CELLSIZEH = AreaY / YYY
Else
ResizeImage(#Image, XXX , YYY, #PB_Image_Smooth)
; ResizeImage(#Image, AreaX , AreaY, #PB_Image_Raw)
EndIf
SetWindowTitle(#Window, "IconEditor (" + Str(XXX) + "x" + Str(YYY) + ")")
DrawImage(ImageID(#Image), 0, 0)
; считываем пиксели рисунка в массив
For y = 0 To YYY - 1
For x = 0 To XXX - 1
tmp = Point(x, y)
; Debug tmp
aIcon(x, y) = tmp
Next
Next
Box(0, 0, AreaX, AreaY, $010203) ; стираем холст
For y = 0 To YYY - 1
For x = 0 To XXX - 1
Select StyleBox
Case 0
Box(x * CELLSIZEW, y * CELLSIZEH, CELLSIZEW, CELLSIZEH, aIcon(x, y))
Case 1
Box(x * CELLSIZEW, y * CELLSIZEH, CELLSIZEW - 1, CELLSIZEH - 1, aIcon(x, y))
Case 2
RoundBox(x * CELLSIZEW + 1, y * CELLSIZEH + 1, CELLSIZEW - 2, CELLSIZEH - 2, 2, 2, aIcon(x, y))
EndSelect
Next
Next
StopDrawing()
EndIf
FreeImage(#Image)
EndIf
EndIf
Case #btnSave
If StartDrawing(CanvasOutput(#cnvScene))
DrawingMode(#PB_2DDrawing_Transparent)
For y = 1 To YYY
For x = 1 To XXX
tmp = Point(x * CELLSIZEW - CELLSIZEW / 2, y * CELLSIZEH - CELLSIZEH / 2)
aIcon(x, y) = tmp
Next
Next
StopDrawing()
If CreateImage(#Image, XXX, YYY, 24, #PB_Image_Transparent)
; If CreateImage(#Image, XXX, YYY)
If StartDrawing(ImageOutput(#Image))
DrawingMode(#PB_2DDrawing_Transparent)
For y = 1 To YYY
For x = 1 To XXX
If aIcon(x, y) <> $010203
Plot(x - 1, y - 1, aIcon(x, y))
EndIf
Next
Next
StopDrawing()
; tmp$ = SaveFileRequester("Выберите файл для сохранения", GetCurrentDirectory(), "img|*.bmp;*.png;*.gif;*.ico", 0)
tmp$ = SaveFileRequester("Select file to save", GetCurrentDirectory(), "*.bmp|*.bmp|*.png|*.png", 0)
If Asc(tmp$)
Select GetExtensionPart(tmp$)
Case "png"
ImagePlugin = #PB_ImagePlugin_PNG
Case "bmp"
ImagePlugin = #PB_ImagePlugin_BMP
Default
tmp$ + ".bmp"
ImagePlugin = #PB_ImagePlugin_BMP
EndSelect
; Debug tmp$
; выводим на холст палитры, всё нормально с изображением
; If StartDrawing(CanvasOutput(#cnvPalette))
; DrawImage(ImageID(#Image), 1, 1)
; StopDrawing()
; EndIf
If SaveImage(#Image, tmp$, ImagePlugin)
MessageRequester("File created", tmp$)
Else
MessageRequester("Error", "Failed to save file")
EndIf
EndIf
EndIf
FreeImage(#Image)
EndIf
EndIf
;- Canvas (event)
Case #cnvPalette
ecnv = EventType()
Select ecnv
Case #PB_EventType_MouseWheel
; Debug
mxx = GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseX)
myy = GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseY)
If mxx > 0 And mxx < 92 And myy > 49 And myy < 151
arr_hsb(1) + GetGadgetAttribute(#cnvPalette, #PB_Canvas_WheelDelta) * 5
If arr_hsb(1) < 0
arr_hsb(1) = 0
Continue
ElseIf arr_hsb(1) > 100
arr_hsb(1) = 100
Continue
EndIf
Debug arr_hsb(1)
If StartDrawing(CanvasOutput(#cnvPalette))
For j = 0 To 90
arr_hsb(2) = 100 - j
For i = 0 To w
arr_hsb(0) = i * 360 / w
hsb_to_rgb()
Plot(j + 1, i + 50, RGB(arr_rgb(0), arr_rgb(1), arr_rgb(2)))
Next
Next
StopDrawing()
EndIf
EndIf
Case #PB_EventType_LeftClick
mxx = GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseX)
myy = GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseY)
; Debug mxx
; Debug myy
If mxx > 0 And mxx < 92 And myy > 49 And myy < 151
If StartDrawing(CanvasOutput(#cnvPalette))
selectedColor = Point(GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseX), GetGadgetAttribute(#cnvPalette, #PB_Canvas_MouseY))
Box(28, 9, 30, 30, selectedColor)
StopDrawing()
EndIf
EndIf
If mxx > 92 And mxx < 104 And myy > 49 And myy < 151
arr_hsb(1) = 150 - myy
; Debug arr_hsb(1)
If StartDrawing(CanvasOutput(#cnvPalette))
For j = 0 To 90
arr_hsb(2) = 100 - j
For i = 0 To w
arr_hsb(0) = i * 360 / w
hsb_to_rgb()
Plot(j + 1, i + 50, RGB(arr_rgb(0), arr_rgb(1), arr_rgb(2)))
Next
Next
StopDrawing()
EndIf
EndIf
EndSelect
Case #cnvScene
ecnv = EventType()
Select ecnv
Case #PB_EventType_RightButtonDown
delmode = 1
DrawPixel(0)
pendown = 1
Case #PB_EventType_LeftButtonDown
DrawPixel(selectedColor)
pendown = 1
Case #PB_EventType_LeftButtonUp, #PB_EventType_RightButtonUp
pendown = 0
delmode = 0
Case #PB_EventType_MouseMove
If pendown = 1
; преобразование в позицию квадратов x, y, чтобы сравнить являются ли квадраты на одной линии
mxx = Int(GetGadgetAttribute(#cnvScene, #PB_Canvas_MouseX) / CELLSIZEW) * CELLSIZEW
myy = Int(GetGadgetAttribute(#cnvScene, #PB_Canvas_MouseY) / CELLSIZEH) * CELLSIZEH
If mxxOld = mxx And myyOld = myy
Continue
Else
mxxOld = mxx
myyOld = myy
EndIf
If StartDrawing(CanvasOutput(#cnvScene))
If delmode
Select StyleBox
Case 0
Box(mxx, myy, CELLSIZEW, CELLSIZEH, 0)
Case 1
Box(mxx, myy, CELLSIZEW - 1, CELLSIZEH - 1, 0)
Case 2
RoundBox(mxx + 1, myy + 1, CELLSIZEW - 2, CELLSIZEH - 2, 2, 2, 0)
EndSelect
Else
Select StyleBox
Case 0
Box(mxx, myy, CELLSIZEW, CELLSIZEH, selectedColor)
Case 1
Box(mxx, myy, CELLSIZEW - 1, CELLSIZEH - 1, selectedColor)
Case 2
RoundBox(mxx + 1, myy + 1, CELLSIZEW - 2, CELLSIZEH - 2, 2, 2, selectedColor)
EndSelect
EndIf
StopDrawing()
EndIf
EndIf
EndSelect
EndSelect
EndSelect
ForEver
; Procedure hsb_to_rgb(arr_hsb)
Procedure hsb_to_rgb()
Protected sector
Protected.f ff, pp, qq, tt
Protected.f Dim af_rgb(2) ; создаём массивы в которых числа будут в диапазоне 0-1
Protected.f Dim af_hsb(2)
; Protected Dim arr_rgb(2)
af_hsb(2) = arr_hsb(2) / 100
If arr_hsb(1) = 0 ; если серый, то одно значение всем
arr_rgb(0) = Round(af_hsb(2) * 255, #PB_Round_Nearest)
arr_rgb(1) = arr_rgb(0)
arr_rgb(2) = arr_rgb(0)
; ProcedureReturn arr_rgb
EndIf
While arr_hsb(0) >= 360 ; если тон задан большим запредельным числом, то
arr_hsb(0) - 360
Wend
af_hsb(1) = arr_hsb(1) / 100
af_hsb(0) = arr_hsb(0) / 60
; sector = Int(arr_hsb(0))
sector = Round(af_hsb(0), #PB_Round_Down)
ff = af_hsb(0) - sector
pp = af_hsb(2) * (1 - af_hsb(1))
qq = af_hsb(2) * (1 - af_hsb(1) * ff)
tt = af_hsb(2) * (1 - af_hsb(1) * (1 - ff))
Select sector
Case 0
af_rgb(0) = af_hsb(2)
af_rgb(1) = tt
af_rgb(2) = pp
Case 1
af_rgb(0) = qq
af_rgb(1) = af_hsb(2)
af_rgb(2) = pp
Case 2
af_rgb(0) = pp
af_rgb(1) = af_hsb(2)
af_rgb(2) = tt
Case 3
af_rgb(0) = pp
af_rgb(1) = qq
af_rgb(2) = af_hsb(2)
Case 4
af_rgb(0) = tt
af_rgb(1) = pp
af_rgb(2) = af_hsb(2)
Default
af_rgb(0) = af_hsb(2)
af_rgb(1) = pp
af_rgb(2) = qq
EndSelect
; RGB
arr_rgb(0) = Round(af_rgb(0) * 255, #PB_Round_Nearest)
arr_rgb(1) = Round(af_rgb(1) * 255, #PB_Round_Nearest)
arr_rgb(2) = Round(af_rgb(2) * 255, #PB_Round_Nearest)
; BGR
; arr_rgb(2)=Round(af_rgb(0)*255, #PB_Round_Nearest)
; arr_rgb(1)=Round(af_rgb(1)*255, #PB_Round_Nearest)
; arr_rgb(0)=Round(af_rgb(2)*255, #PB_Round_Nearest)
; ProcedureReturn arr_rgb
EndProcedure
Procedure rgb_to_hsb()
Protected.f min, max
If arr_rgb(0) <= arr_rgb(1)
min = arr_rgb(0)
max = arr_rgb(1)
Else
min = arr_rgb(1)
max = arr_rgb(0)
EndIf
If min > arr_rgb(2)
min = arr_rgb(2)
EndIf
If max < arr_rgb(2)
max = arr_rgb(2)
EndIf
If max = min
arr_hsb(0) = 0
ElseIf max = arr_rgb(0)
arr_hsb(0) = 60 * (arr_rgb(1) - arr_rgb(2)) / (max - min)
If arr_rgb(1) < arr_rgb(2)
arr_hsb(0) + 360
EndIf
ElseIf max = arr_rgb(1)
arr_hsb(0) = 60 * (arr_rgb(2) - arr_rgb(0)) / (max - min) + 120
ElseIf max = arr_rgb(2)
arr_hsb(0) = 60 * (arr_rgb(0) - arr_rgb(1)) / (max - min) + 240
EndIf
If max = 0
arr_hsb(1) = 0
Else
arr_hsb(1) = (1 - min / max) * 100
EndIf
arr_hsb(2) = max / 255 * 100
arr_hsb(0) = Round(arr_hsb(0), #PB_Round_Nearest)
arr_hsb(1) = Round(arr_hsb(1), #PB_Round_Nearest)
arr_hsb(2) = Round(arr_hsb(2), #PB_Round_Nearest)
; ProcedureReturn arr_hsb
EndProcedure