@@ -2,16 +2,44 @@ import std/[strutils, tables, algorithm]
22
33import  ../ [ view, text_field, matrixes, image, button, color_picker,
44  context, portable_gl, layout, popup_button, font, property_visitor,
5-   numeric_text_field, system_logger, image_preview ]
6- 
5+   numeric_text_field, system_logger, image_preview, drag_and_drop,
6+   render_to_image
7+ ]
8+ import  ../ pasteboard/ pasteboard_item
9+ import  ../ assets/ asset_loading
710import  ./ propedit_registry
811import  variant
912
13+ 
1014when  defined (js):
1115  from  dom import  alert, window
1216elif  not  defined (android) and  not  defined (ios):
1317  import  os_files/ dialog
1418
19+ type 
20+   NimxImageEditorDropDelegate *  =  ref  object  of  DragDestinationDelegate 
21+     callback: proc (i: Image ) {.gcsafe .}
22+ 
23+ const  nimxPbImage*  =  " nimx.pb.image" 
24+ 
25+ method  onDragEnter * (dd: NimxImageEditorDropDelegate , target: View , i: PasteboardItem ) = 
26+   if  i.kind ==  nimxPbImage:
27+     target.backgroundColor.a =  0.5 
28+ 
29+ method  onDragExit * (dd: NimxImageEditorDropDelegate , target: View , i: PasteboardItem ) = 
30+   if  i.kind ==  nimxPbImage:
31+     target.backgroundColor.a =  0.0 
32+ 
33+ method  onDrop * (dd: NimxImageEditorDropDelegate , target: View , i: PasteboardItem ) = 
34+   target.backgroundColor.a =  0.0 
35+   if  i.kind ==  nimxPbImage:
36+     loadAsset [Image ](" file://" &  i.data) do (image: Image , err: string ):
37+       if  image.isNil:
38+         echo  " Can't load image from " 
39+         return 
40+       if  not  dd.callback.isNil:
41+         dd.callback (image)
42+ 
1543template  toStr (v: SomeFloat , precision: uint ): string  =  formatFloat (v, ffDecimal, precision)
1644template  toStr (v: SomeInteger ): string  =  $ v
1745
@@ -397,26 +425,60 @@ proc newFontPropertyView(setter: proc(s: Font) {.gcsafe.}, getter: proc(): Font
397425  result  =  r
398426
399427when  not  defined (android) and  not  defined (ios):
428+ 
429+   type 
430+     ButtonImageView  =  ref  object  of  Button 
431+       originalImage: Image 
432+ 
433+   proc  `onImageDropped=` (v: ButtonImageView , cb: proc (i: Image ){.gcsafe .}) = 
434+     v.dragDestination.NimxImageEditorDropDelegate .callback =  cb
435+ 
436+   method  init * (v: ButtonImageView ) = 
437+     procCall  v.Button .init ()
438+     v.hasBezel =  false 
439+     v.dragDestination =  new (NimxImageEditorDropDelegate )
440+ 
441+   method  draw * (v: ButtonImageView , r:Rect ) = 
442+     let  c =  currentContext ()
443+     c.fillColor =  v.backgroundColor
444+     c.drawRect (r)
445+ 
446+     if  v.originalImage.isNil: return 
447+     if  v.image.isNil and  v.originalImage.size.width >  v.frame.width or  v.originalImage.size.height >  v.frame.height:
448+       let  imageSize =  min (v.frame.width, v.frame.height)
449+       let  scale =  imageSize /  max (v.originalImage.size.width, v.originalImage.size.height)
450+       let  img =  imageWithSize (newSize (imageSize, imageSize))
451+       img.draw:
452+         c.drawImage (v.originalImage, newRect (1 , 1 , v.originalImage.size.width *  scale -  1 , v.originalImage.size.height *  scale -  1 ))
453+       v.image =  img
454+     else :
455+       v.image =  v.originalImage
456+ 
457+     const  offset =  2 
458+     c.drawImage (v.image, newRect (r.x +  offset, r.y +  offset, r.width -  offset* 2 , r.height -  offset* 2 ))
459+ 
400460  proc  newImagePropertyView (setter: proc (s: Image ) {.gcsafe .}, getter: proc (): Image  {.gcsafe .}): PropertyEditorView  = 
401461    var  loadedImage =  getter ()
462+     proc  imageDropped (i: Image ) {.gcsafe .}
402463    let  r =  new (PropertyEditorView )
403464    r.makeLayout:
404-       -  Button  as  imagePlac:
465+       -  ButtonImageView  as  imagePlac:
405466        top ==  super
406467        leading ==  super
407468        width ==  128 
408469        height ==  128 
409470        hasBezel: false 
410-         image: loadedImage
411471        backgroundColor: newColor (0.222 , 0.444 , 0.666 )
472+         originalImage: loadedImage
412473        onAction:
413474          if  imagePlac.image.isNil:
414475            return 
415476
416477          var  imagePreview =  new (ImagePreview )
417-           imagePreview.image =  imagePlac.image 
478+           imagePreview.image =  imagePlac.originalImage 
418479          imagePreview.popupAtCenterOfWindow ()
419- 
480+         onImageDropped  do (i: Image ):
481+           imageDropped (i)
420482      -  View :
421483        top ==  super
422484        bottom ==  super
@@ -464,7 +526,8 @@ when not defined(android) and not defined(ios):
464526                var  i: Image 
465527                try :
466528                  i =  imageWithContentsOfFile (path)
467-                   imagePlac.image =  i
529+                   imagePlac.originalImage =  i
530+                   imagePlac.image =  nil 
468531                  widthLabel.text =  " w:" &  $ i.size.width
469532                  heightLabel.text =  " h:" &  $ i.size.height
470533                except :
@@ -474,10 +537,18 @@ when not defined(android) and not defined(ios):
474537                  #  if not pv.changeInspector.isNil:
475538                  #    pv.changeInspector()
476539
540+     proc  imageDropped (i: Image ) {.gcsafe .} = 
541+       imagePlac.originalImage =  i
542+       imagePlac.image =  nil 
543+       widthLabel.text =  " w:" &  $ i.size.width
544+       heightLabel.text =  " h:" &  $ i.size.height
545+       setter (i)
546+ 
477547    if  not  loadedImage.isNil:
478548      widthLabel.text =  " w:" &  $ loadedImage.size.width
479549      heightLabel.text =  " h:" &  $ loadedImage.size.height
480550    result  =  r
551+ 
481552  registerPropertyEditor (newImagePropertyView)
482553
483554registerPropertyEditor (newTextPropertyView)
0 commit comments