package com.github.irshulx.Components; import android.app.Activity; import android.graphics.Color; import android.text.TextUtils; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.github.irshulx.EditorCore; import com.github.irshulx.EditorComponent; import com.github.irshulx.R; import com.github.irshulx.Utilities.Utilities; import com.github.irshulx.models.EditorContent; import com.github.irshulx.models.EditorControl; import com.github.irshulx.models.EditorType; import com.github.irshulx.models.Node; import com.github.irshulx.models.RenderType; import org.jsoup.nodes.Attribute; import org.jsoup.nodes.Element; import java.util.HashMap; import java.util.List; import java.util.Map; public class MacroExtensions extends EditorComponent { private final EditorCore editorCore; public MacroExtensions(EditorCore editorCore) { super(editorCore); this.editorCore = editorCore; } public void insertMacro(String name, View view, Map<String, Object> settings, int index) { final FrameLayout frameLayout = new FrameLayout(editorCore.getContext()); frameLayout.addView(view); final FrameLayout overlay = new FrameLayout(frameLayout.getContext()); overlay.setVisibility(View.GONE); overlay.setPadding(0, 0, 20, 0); overlay.setBackgroundColor(Color.argb(50, 0, 0, 0)); ImageView imageView = new ImageView(overlay.getContext()); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(Utilities.dpToPx(frameLayout.getContext(), 40), Utilities.dpToPx(frameLayout.getContext(), 40)); params.gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL; imageView.setLayoutParams(params); imageView.setImageResource(R.drawable.ic_close_white_36dp); overlay.addView(imageView); frameLayout.addView(overlay); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { editorCore.getParentView().removeView(frameLayout); } }); EditorControl control = editorCore.createTag(EditorType.macro); control.macroSettings = settings; control.macroName = name; if (index == -1) { index = editorCore.determineIndex(EditorType.macro); } frameLayout.setTag(control); // frameLayout.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View view) { // if(overlay.getVisibility()==View.VISIBLE){ // overlay.setVisibility(View.GONE); // }else{ // overlay.setVisibility(View.VISIBLE); // } // } // }); editorCore.getParentView().addView(frameLayout, index); if(editorCore.getRenderType() == RenderType.Renderer) return; view.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { int paddingTop = view.getPaddingTop(); int paddingBottom = view.getPaddingBottom(); int height = view.getHeight(); if (event.getY() < paddingTop) { editorCore.___onViewTouched(0, editorCore.getParentView().indexOfChild(frameLayout)); } else if (event.getY() > height - paddingBottom) { editorCore.___onViewTouched(1, editorCore.getParentView().indexOfChild(frameLayout)); } else { if (overlay.getVisibility() == View.VISIBLE) { overlay.setVisibility(View.GONE); } else { overlay.setVisibility(View.VISIBLE); } } return false; } return true;//hmmmm.... } }); frameLayout.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean b) { if(!b){ overlay.setVisibility(View.GONE); } } }); } @Override public Node getContent(View view) { Node node = this.getNodeInstance(view); EditorControl macroTag = (EditorControl) view.getTag(); node.content.add(macroTag.macroName); node.macroSettings = macroTag.macroSettings; return node; } @Override public String getContentAsHTML(Node node, EditorContent content) { return getAsHtml(node.content.get(0), node.macroSettings); } private String getAsHtml(String name, Map<String, Object> macroSettings){ String template = "<{{$tag}} data-tag=\"macro\" {{$settings}}></{{$tag}}>"; template = template.replace("{{$tag}}", name); StringBuilder dataTags = new StringBuilder(); for (Map.Entry<String, Object> item : macroSettings.entrySet()) { if(item.getKey().equalsIgnoreCase("data-tag")) continue; dataTags.append(" "); if(item.getKey().contains("data-")){ dataTags.append(item.getKey()); }else { dataTags.append("data-" + item.getKey()); } dataTags.append("=\"").append(String.valueOf(item.getValue())).append("\""); } if (TextUtils.isEmpty(dataTags)) { template = template.replace("{{$settings}}", ""); } else { template = template.replace("{{$settings}}", dataTags.toString()); } return template; } @Override public void renderEditorFromState(Node node, EditorContent content) { int index = editorCore.getChildCount(); View view = editorCore.getEditorListener().onRenderMacro(node.content.get(0), node.macroSettings, editorCore.getChildCount()); if(view == null) view = getEmptyMacro(node.content.get(0),node.macroSettings); insertMacro(node.content.get(0), view, node.macroSettings, index); } private View getEmptyMacro(String name, Map<String, Object> macroSettings){ final View layout = ((Activity) editorCore.getContext()).getLayoutInflater().inflate(R.layout.default_macro, null); TextView message = layout.findViewById(R.id.txtMessage); message.setText("Unhandled macro "+ "\""+getAsHtml(name,macroSettings)+"\""); return layout; } @Override public Node buildNodeFromHTML(Element element) { String tag = element.tagName().toLowerCase(); Node node = getNodeInstance(EditorType.macro); node.content.add(tag); List<Attribute> attrs = element.attributes().asList(); if (!attrs.isEmpty()) { node.macroSettings = new HashMap<>(); for (Attribute attr : attrs) { node.macroSettings.put(attr.getKey(), attr.getValue()); } } int index = editorCore.getChildCount(); View view = editorCore.getEditorListener().onRenderMacro(tag, node.macroSettings, editorCore.getChildCount()); if(view == null) view = getEmptyMacro(node.content.get(0), node.macroSettings); insertMacro(tag, view, node.macroSettings, index); return null; } @Override public void init(ComponentsWrapper componentsWrapper) { this.componentsWrapper = componentsWrapper; } }