/
nea
/
androidGroupBuilder
Обзор
Документация
Войти
/
nea
/
androidGroupBuilder
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/src/main/java/com/ea/groupbuilder/SurfaceHolderActivity.java
937 строк
45 KB
ea
Группа Автоморфизмов отлажено 23_04_2026
23 апр 2026, 17:08
23 апр 2026, 17:08
4513276
Код
Авторство
О чём код?
package com.ea.groupbuilder; import static java.lang.Math.PI; import static java.lang.Math.cos; import static java.lang.Math.floor; import static java.lang.Math.min; import static java.lang.Math.sin; import android.content.Intent; import android.content.pm.ActivityInfo; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.graphics.Canvas; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; public abstract class SurfaceHolderActivity extends AppCompatActivity implements SurfaceHolder.Callback { // предок классов RnActivity и kelyActivity private final static String TAG = "GRUGRA_SH"; final static private boolean DISPLAYLOG = false; protected List<dataPoint> valDataRect = new ArrayList(); // список всех объектов точки dataSubs protected List<dataLines> valDataLines = new ArrayList(); // список всех линий dataLines protected int axisFlg = 0, // отображать оси gruppFlg = 1, // 1 - Отобразить группу lineFlg = -1, // 0 - отображать все ребра, -1 - не отображать, 1 - id ребер для отображения в masIdPostSelRebro lineCreated = 0, // 0 - f_getLinesBuff() нужно выполнить, 1 - не надо pntFlg = 0, // 1 - отображать все целочисленные точки kakBuild = 1, // как строить (по итерациям.,,,) kakKolop = 1; // как раскрашивать kelyActivity protected boolean flagSn = false; // Sn отображать? static protected List<Integer> setkaOs = new ArrayList<>(); protected int sh = 0, sw = 0; // размеры экрана protected double dx = 0, dy = 0; // координаты центра = точки {0,0,0} protected float startX = 0f, startY = 0f; // смещение по сдвигу по 2 пальцам protected int modeGroupFlag = -1; // как выделить вершины в RnActivitySelect, см valuesColorText - выделить класс,... // = -10 - выделение распавшихся кллассов // = -3 - убрать все выделения, ребра могут не показываться в зависимости от checkBoxVal в modeGroupFlag кнопка СБРОС protected volatile int elemFlg = 0; // 1 - был выбор элементов по ModeActivitySize, выполнить f_elementSelect protected String modelGroupNum = "", // RnActivitySelect уточнение, что выбрано (номер класса,...) insrtStr = ""; // строка заполнения temp_pe строится в RnActivitySelect protected volatile int menuFlg = 0; /* 1 - выделение из меню (вызвать f_menuSelect();) 2 - из меню выбрано "Оставить только" тоже со зноком "-" - параметр для RnActivitySelect */ protected volatile int autoFlg = 0; /* 0 - не рисовать 3 - автоморф Один на выделенные элементы 4 - Все автоморф на выделенные элементы */ protected volatile int modeSizeParm = 0; /* для ModeActivitySize: = 1; // Выделение элементов для отображения = 2; // выбор автоморф */ protected int posCreated = 0; /* 0 - f_readData нужно выполнить (и f_setPos() - заносит x,y в объекты точки dataSubs) 1 - изменение масштаба 2 - пересчитать матрицу и координаты (не отработал f_setPos()) */ protected String txtSoobColor = "", txtSoobSelect = "", txtSoobTouch = ""; // текст сообщения protected String groupName_n = ""; protected DbHelper dbH; protected mAplication mApp; protected substitutionS classSubs; protected SurfaceView view; protected PaintAll paintKal = null; final protected colorSelector colorSlt = new colorSelector(); protected Canvas canvas = null; protected volatile boolean IsCreat = false; // не созданы final static protected Paint paintTxt = new Paint(Paint.ANTI_ALIAS_FLAG), paintPoint = new Paint(Paint.ANTI_ALIAS_FLAG), paintOs = new Paint(Paint.ANTI_ALIAS_FLAG), paintSetka = new Paint(Paint.ANTI_ALIAS_FLAG), paintZag = new Paint(Paint.ANTI_ALIAS_FLAG), paintClick = new Paint(Paint.ANTI_ALIAS_FLAG), paintSubGr = new Paint(Paint.ANTI_ALIAS_FLAG), paintAuto = new Paint(Paint.ANTI_ALIAS_FLAG), paintArr = new Paint(Paint.ANTI_ALIAS_FLAG) ; protected static SQLiteDatabase db = null; private FloatingActionButton fab; protected TextView txtSoob; private final Timer tmr = new Timer(); // задает мигание для групп с заданным классом static protected volatile boolean tnrFlag = false; // признак рисовать или нет группу - используется таймером protected Finger fing[] = new Finger[] {new Finger(), new Finger(), new Finger()}; // состояние пальцев protected double otstup = 0d, // отступ сверху экрана koeffX = 0d; // коэфф сжатия/ растяжения protected ProgressBar ProgressBr; // вращать в плоскости посдедних 2-х осей movO1, movO2 protected volatile boolean flagMove = false; // флаг @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setContentView(R.layout.activity_norm_sub); view = findViewById(R.id.norm_view); view.getHolder().addCallback(this); txtSoob = findViewById(R.id.grzak_norm); // сообщенин внизу ProgressBr = (ProgressBar) findViewById(R.id.pbloadingrn); ProgressBr.setIndeterminate(false); mApp = (mAplication) getApplication(); dbH = mApp.dbH; db = DbHelper.db; DbHelper.err = ""; if (DISPLAYLOG) Log.e(TAG, "onCreate dbH.faktSubsLen = " + dbH.faktSubsLen ); if (dbH.f_testFn()) groupName_n = dbH.f_getString("select distinct val_txt as stext from params where parm = 'GroupName_n';"); // Log.e(TAG, "onCreate posCreated = " + posCreated + " dbH.f_testFn() = " + dbH.f_testFn()); fab = findViewById(R.id.fab); fab.setOnClickListener(view -> { PopupMenu popupMenu = new PopupMenu(getApplicationContext(), fab); popupMenu.inflate(R.menu.menu_rn_popup); Menu pMenu = popupMenu.getMenu(); popupMenu.show(); popupMenu.setOnMenuItemClickListener(item -> { Intent intent; switch (item.getItemId()) { // выделение по insrtStr case R.id.action_rn_klass: // Выделить ... menuFlg = -1; if (DISPLAYLOG) Log.e(TAG, "onCreate fab Выделить menuFlg= " + menuFlg ); intent = new Intent(mApp.getApplicationContext(), RnActivitySelect.class); startActivity(intent); break; case R.id.action_grp_gsel_class: // Выделение распавшихся классов insrtStr = classKely.f_setInsetr(16, "", flagSn, dbH); // устанавливает kelyActivity.valuesColorText для выбора по fab txtSoobSelect = "Выделение распавшихся классов"; menuFlg = 1; if (DISPLAYLOG) Log.e(TAG, "onCreate fab Выделить menuFlg= " + menuFlg ); break; // Оставить по insrtStr case R.id.action_rd_klass: // Оставить menuFlg = -2; if (DISPLAYLOG) Log.e(TAG, "onCreate fab удалить menuFlg= " + menuFlg ); intent = new Intent(mApp.getApplicationContext(), RnActivitySelect.class); startActivity(intent); break; case R.id.action_rn_get_rebro: // Выбор образующего (ребра) f_initModeSize(0); if (DISPLAYLOG) Log.e(TAG, "onCreate fab Выбор образующего (ребра) menuFlg= " + menuFlg ); // заполняет masIdPostSelRebro и lineFlg intent = new Intent(mApp.getApplicationContext(), ModeActivityLine.class); startActivity(intent); break; case R.id.action_rn_get_element: // Выделение элементов для отображения if (DISPLAYLOG) Log.e(TAG, "onCreate fab удалить menuFlg= " + menuFlg ); f_initModeSize(0); modeSizeParm = 1; // Выделение элементов для отображения intent = new Intent(mApp.getApplicationContext(), ModeActivitySize.class); startActivity(intent); posCreated = 0; break; case R.id.action_grp_l_reset: // Сброс f_allClaer(); break; default: break; } return true; } ); }); } protected void f_allClaer() { // сброс всех сдвигов txtSoobColor = ""; txtSoobSelect = ""; } protected String masIdForSelElements[]; // список отображеннных Id static protected List<Integer> masIdPostSelRebro = new ArrayList<>(); // список выбанных в ModeActivityLine для отображения Id образующих private void f_initModeSize(int chego) { // chego = 0 - заполняет masIdForSelElements - список отображеннных Id для выбора: masIdForSelElements[i] = '8 [2, 1, 4, 3] (1, 2)(3, 4) aab' // = 1 - автоморф Один на выделенные элементы int j, rc; switch (chego) { case 0: masIdForSelElements = new String[valDataRect.size()]; for (int i = 0; i < valDataRect.size(); i++) { masIdForSelElements[i] = valDataRect.get(i).id + " " + valDataRect.get(i).f_getSubs() + " " + valDataRect.get(i).f_getNameSub(flagSn); if (DISPLAYLOG) Log.e(TAG, "f_initModeSize i = " + i + " masIdForSelElements[i] = " + masIdForSelElements[i]); } break; case 1: // автоморф на выделенные элементы rc = dbH.f_getMas("select distinct _id ||' ' ||ciklos|| ' P = ' || pe || ' ' || name as stext from elements_a order by 1 asc;"); masIdForSelElements = new String[rc]; masIdForSelElements = Arrays.copyOf(DbHelper.selectedMas, rc); break; } } protected void f_set() { // выполняется 1 раз paintPoint.setStyle(Paint.Style.FILL_AND_STROKE); // точки paintPoint.setStrokeWidth(5.9f); paintPoint.setARGB(255, 0, 0, 255); paintPoint.setAntiAlias(true); paintSubGr.setStyle(Paint.Style.FILL); // РЕБРА paintSubGr.setStrokeWidth(2); paintSubGr.setARGB(255, 255, 0, 255); paintAuto.setStyle(Paint.Style.FILL_AND_STROKE); // автомор paintAuto.setStrokeWidth(3); paintAuto.setStyle(Paint.Style.STROKE); paintAuto.setStrokeCap(Paint.Cap.ROUND); // Делает концы линий (и точки) круглыми // Настройка эффекта: // 0f — длина штриха; (точка), 18f — расстояние между точками paintAuto.setPathEffect(new DashPathEffect(new float[]{0f, 18f}, 0f)); paintArr.setStrokeCap(Paint.Cap.ROUND); // Делает концы линий (и точки) круглыми paintArr.setStyle(Paint.Style.FILL); // заливаем paintClick.setStyle(Paint.Style.STROKE); paintClick.setStrokeWidth(12); paintClick.setARGB(255, 255, 0, 255); paintTxt.setStyle(Paint.Style.STROKE); paintTxt.setStrokeWidth(0.8f); paintTxt.setTextSize(18); paintTxt.setARGB(255, 0, 0, 0); paintOs.setStyle(Paint.Style.FILL); // оси paintOs.setStrokeWidth(1); paintOs.setTextSize(18); paintOs.setARGB(125, 250, 0, 0); paintSetka.setStyle(Paint.Style.STROKE); // точки осей и сетка paintSetka.setStrokeWidth(3); paintSetka.setARGB(70, 30, 30, 30); paintZag.setStyle(Paint.Style.FILL); // ребра, циклы paintZag.setStrokeWidth(0.8f); paintZag.setTextSize(18); paintZag.setARGB(255, 0, 0, 0); classSubs = mApp.classSubs; // substitutionS dbH.f_getParm(1, 8, flagSn ? 1 : 0); // DbHelper.faktSubsLen - степень группы db.execSQL("delete from temp_pe;"); tmr.scheduleAtFixedRate(new TimerTask() { // для мигания - public void run() { tnrFlag = !tnrFlag; } }, 0, 600); // каждые 0.7 секунд if (DISPLAYLOG) Log.e(TAG, "f_set faktSubsLen = " + DbHelper.faktSubsLen + " " + cos(PI / 3.) + " " + sin(PI / 2)); } protected void f_getLinesBuff() { // построение линий. заполняет табл lines, points д б заполнена final String sqL[] = { "delete from lines;", "UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='lines';", "delete from temp_elements;", "UPDATE SQLITE_SEQUENCE SET SEQ=0 WHERE NAME='temp_elements';", (flagSn ? // запись линий, nomer = 1 - рисовать линию, 0 - нет - сделан выбор в ModeActivityLine "insert into lines (id_1, id_2, name, id_start, ind1, ind2, color, nomer) \n" + "select M.idleft, M.idproiz, E.name, E.id_true, 0, 0, 0, 1 " + "from elements_n E, temp_multiplication_n M\n" + " where E.id_true = M.idright and E.iteration = 0" + " and E.for_n <= " + DbHelper.faktSubsLen + "\n" + " order by E.name asc; " : "insert into lines (id_1, id_2, name, id_start, ind1, ind2, color, nomer) \n" + "select M.idleft, M.idproiz, E.name, E._id, 0, 0, 0, 1 from elements" + mApp.tableNameEnd + " E, temp_multiplication" + mApp.tableNameEnd + " M \n" + " where E._id = M.idright and E.iteration = 0 order by E.name asc; " ), "update lines set ind1 = (" + // запись индексов точек "select ind_point from points where id_element = id_1); ", "update lines set ind2 = (" + "select ind_point from points where id_element = id_2); ", "insert into temp_elements (id, txt) " + // образующие для записи цвета "select distinct id_start, name from lines order by 1 asc;", "update lines set color = (" + "select _id from temp_elements where id_start = id); ", "delete from lines where ind1 is null or ind2 is null;" }; // заполняю табл lines for (String s : sqL) db.execSQL(s); valDataLines.clear(); String sqlLine = "select name, color, ind1, ind2, id_start from lines order by id_start asc; ", name = ""; Cursor cursorGrPt = SurfaceHolderActivity.db.rawQuery(sqlLine, null); int ind_1 = cursorGrPt.getColumnIndex("ind1"), // начало ind_2 = cursorGrPt.getColumnIndex("ind2"), // начало id_ = cursorGrPt.getColumnIndex("id_start"), // _id образующего indName = cursorGrPt.getColumnIndex("name"), ind_col = cursorGrPt.getColumnIndex("color"), // конец i1, i2, col, id, id0 = -1; dataLines DataLn; if (cursorGrPt.getCount() > 0) { if (cursorGrPt.moveToFirst()) { do { id = cursorGrPt.getInt(id_); // _id образующего if (lineFlg == 0 ||(lineFlg > 0 && masIdPostSelRebro.contains(id))) { i1 = cursorGrPt.getInt(ind_1); i2 = cursorGrPt.getInt(ind_2); name = cursorGrPt.getString(indName); col = cursorGrPt.getInt(ind_col); DataLn = new dataLines(id, i1, i2, col, name); valDataLines.add(DataLn); if (id != id0) { DataLn.outStr = 1; id0 = id; } /* if (DISPLAYLOG) if (name.equals("a")) Log.e(TAG, "f_getLinesBuff id = " + id + " line= " + name + " t1= " + valDataRect.get(i1).id + " " + valDataRect.get(i1).xPos[0] + " " + valDataRect.get(i1).xPos[1] + " t2= " + valDataRect.get(i2).id + " " + valDataRect.get(i1).xPos[0] + " " + valDataRect.get(i1).xPos[1] + " size= "+ masIdPostSelRebro.size() + " idleft=" + i1 + " idproiz= " + i2 + " col=" + col + " sqlInsLine=" + sqlLine); */ /* if (name.equals("a")) Log.e(TAG, "f_getLinesBuff id = " + id + " line= " + name + " t1= " + valDataRect.get(i1).id + " t2= " + valDataRect.get(i2).id + " idleft=" + i1 + " idproiz= " + i2 + " size= "+ masIdPostSelRebro.size() + " col=" + col + " sqlInsLine=" + sqlLine); */ } } while (cursorGrPt.moveToNext()); } } cursorGrPt.close(); // Log.e(TAG, "f_getLinesBuff lineFlg = " + lineFlg + " valDataLines = " + valDataLines.size() + " posCreated = " + posCreated + " size= "+ masIdPostSelRebro.size() + " sqlInsLine=" + sqlLine); } private int createAuto = 0; // 0 - создать табл temp_prim; 2 - создана табл temp_prim protected void f_setAuto() { // запустить выбор автоморф autoFlg = 3; createAuto = 0; posCreated = 0; f_initModeSize(1); modeSizeParm = 2; // выбор автоморф в ModeActivitySize Intent intent = new Intent(mApp.getApplicationContext(), ModeActivitySize.class); startActivity(intent); } protected void f_putAuto() { /* выбор автоморф сделан рисование действия автом по autoFlg = 0 - не рисовать 3 - автоморф Один на выделенные элементы 4 - Все автоморф на выделенные элементы в temp_auto id_1 = _id автоморфизмов */ // Log.e(TAG, "f_putAuto createAuto = " + createAuto + " autoFlg = " + autoFlg); if (createAuto == 0) { switch (autoFlg) { case 3: db.execSQL("delete from temp_prim;"); db.execSQL("insert INTO temp_prim (pe, id_1, id_2, id_s)\n" + "select distinct SI.pe, SI._id, substr(F.text_sub, 2 + 5*(SI._id - 1), 4), F.id_s \n" + " from elements SI, sub_scribe_a F, temp_auto T \n" + " where F.id_s = T.id_1 \n" + " order by F.id_s asc, SI._id asc;"); // в temp_prim id_1 - до, id_2 - после, id_s - id auto все эл-ты группы для автом из temp_auto db.execSQL("update temp_prim set (deg) = \n" + " (SELECT ind_point\n" + " FROM points\n" + " where temp_prim.id_1 = points.npp \n" + // npp = id G ")"); db.execSQL("update temp_prim set (ndeg) = \n" + " (SELECT ind_point\n" + " FROM points\n" + " where temp_prim.id_2 = points.npp \n" + ")"); // в temp_prim deg = индекс id_1, ndeg - индекс id_2 в valDataRect createAuto = 2; break; case 4: break; } } // собственно рисование String selStr = "select id_1, id_2, id_s, deg, ndeg from temp_prim order by id_s asc;"; Cursor cursorA = db.rawQuery(selStr, null); int ind1 = cursorA.getColumnIndex("deg"), ind2 = cursorA.getColumnIndex("ndeg"), iis = cursorA.getColumnIndex("id_s"), i1, i2, ids, rj = 2, k, m = valDataRect.size(), idsP = -1; dataPoint dpFrom, dpTo; if (lineFlg < 0) startPY = sh / 8f; Paint.FontMetrics fMetr = paintZag.getFontMetrics(); deltaY = fMetr.descent - fMetr.ascent + fMetr.leading; // высота строки https://stackoverflow.com/questions/9364509/android-measure-text-height-on-a-canvas // определяю rj - на каких точках рисовать for (k = 0; k < m; k++) if (valDataRect.get(k).clickFlag) { rj = 0; break; } if (rj == 2) for (k = 0; k < m; k++) if (valDataRect.get(k).selectFlag) { rj = 1; break; } if (cursorA.moveToFirst()) { // Log.e(TAG, "f_putAuto cursorA = " + cursorA.getCount() ); if (cursorA.getCount() > 0) { do { i1 = cursorA.getInt(ind1); // индекс точки ДО i2 = cursorA.getInt(ind2); // индекс точки ПОСДЕ dpFrom = valDataRect.get(i1); // отопрожается если dsb.clickFlag - они выводятся, иначе dSub.selectFlag, если нет и этого - на все точки k = 0; switch (rj) { case 0: if (dpFrom.clickFlag) k = 1; break; case 1: if (dpFrom.selectFlag) k = 2; break; default: k = 3; break; } if (k > 0) { // только для выделенных dpTo = valDataRect.get(i2); ids = cursorA.getInt(iis); // id автом colorSelector.indColor = ids; colorSlt.f_setColor(); paintAuto.setARGB(255, colorSelector.rCol, colorSelector.gCol, colorSelector.bCol); canvas.drawLine(dpFrom.xPos[0] + startX, dpFrom.xPos[1] + startY, dpTo.xPos[0] + startX, dpTo.xPos[1] + startY, paintAuto); if (idsP != ids) { // рисование линий Отображены автоморфизмы if (idsP < 0) { paintZag.setARGB(100, 0, 0, 0); canvas.drawText("Отображены автоморфизмы:", startPX, startPY, paintZag); startPY += deltaY; } canvas.drawLine(startPX, startPY - 4f, startPX + 32f, startPY - 4f , paintAuto); paintZag.setARGB(255, colorSelector.rCol, colorSelector.gCol, colorSelector.bCol); canvas.drawText("id = " + ids, startPX + 35f, startPY, paintZag); startPY += deltaY; idsP = ids; } // рисование стрелок - направление автоморфизма float x1 = dpFrom.xPos[0] + startX, y1 = dpFrom.xPos[1] + startY, x2 = dpTo.xPos[0] + startX, y2 = dpTo.xPos[1] + startY; float aa = 16; double xv = x2 - x1, // вектор с концом в конечной точке yv = y2 - y1, ugS; if (xv > 0.) { ugS = Math.atan(yv / xv) + PI - 0.1 * PI; } else if (xv < 0.) { ugS = Math.atan(yv / xv) - 0.1 * PI; } else { // xv == 0. if (yv > 0.) { ugS = 0.5 * PI - 0.1 * PI; } else { ugS = -0.5 * PI - 0.1 * PI; } } // Log.e(TAG, "f_putAuto dpFrom.id = " + dpFrom.id + " dpTo.id = " + dpTo.id + " x1 = " + x1+ " y1 = " + y1+ " x2 = " + x2+ " y2 = " + y2 + " xv" + xv+ " yv = " + yv + " ugS = " + ugS ); paintArr.setARGB(255, colorSelector.rCol, colorSelector.gCol, colorSelector.bCol); canvas.drawArc( x2 - aa, y2 - aa, x2 + aa, y2 + aa, (float) (ugS * 180f / PI), 25f, true, paintArr); } } while (cursorA.moveToNext()); } } cursorA.close(); } protected float startPX = 14f, startPY = sh / 8f, deltaY; // для рисования обозначений линий protected void f_putLines() { // вывод линий из valDataLines на canvas int i1, i2; startPY = sh / 8f; dataLines dln; dataPoint dSub, dSub1; Paint.FontMetrics fMetr = paintZag.getFontMetrics(); deltaY = fMetr.descent - fMetr.ascent + fMetr.leading; // высота строки https://stackoverflow.com/questions/9364509/android-measure-text-height-on-a-canvas paintZag.setARGB(100, 0, 0, 0); canvas.drawText("Отображены ребра:", startPX, startPY, paintZag); startPY += deltaY; for (int m = 0; m < valDataLines.size(); m++) { dln = valDataLines.get(m); i1 = dln.indPoint1; i2 = dln.indPoint2; dSub = valDataRect.get(i1); dSub1 = valDataRect.get(i2); colorSelector.indColor = dln.colLine; colorSlt.f_setColor(); paintZag.setARGB(255, colorSelector.rCol, colorSelector.gCol, colorSelector.bCol); if (dln.nameLine.contains("^")) canvas.drawLine(dSub.xPos[0] + 2 + startX, dSub.xPos[1] + startY, dSub1.xPos[0] + 2 + startX, dSub1.xPos[1] + startY, paintZag); else canvas.drawLine(dSub.xPos[0] + startX, dSub.xPos[1] + startY, dSub1.xPos[0] + startX, dSub1.xPos[1] + startY, paintZag); if (dln.outStr > 0) { canvas.drawLine(startPX, startPY - 4f, startPX + 27f, startPY - 4f , paintZag); canvas.drawText(dln.nameLine, startPX + 30f, startPY, paintZag); /* if (DISPLAYLOG) { Log.e(TAG, "f_putLines lineFlg= " + lineFlg + " startPX = " + startPX + " startPY = " + startPY + " colLine " + dln.colLine + " dln.outStr= " + dln.outStr + " deltaY = " + deltaY); } */ startPY += deltaY; } } } protected void f_paintPoint(dataPoint dsb) { // вывод обычной точки или единицы if (flagSn && dsb.idSub == 0) paintPoint.setStrokeWidth(3.8f); else paintPoint.setStrokeWidth(5.9f); if (dsb.clickFlag) { // выбрана точка colorSelector.indColor = dsb.colorNum; colorSlt.f_setColor(); paintClick.setARGB(255, colorSelector.rCol, colorSelector.gCol, colorSelector.bCol); canvas.drawPoint(dsb.xPos[0] + startX, dsb.xPos[1] + startY, paintClick); } else { if (dsb.id == substitutionS.codEdinicy && ! flagSn || flagSn && dsb.id == substitutionS.codEdinicy_n) // canvas.drawCircle(dsb.xPos[0], dsb.xPos[1], 1.7f, paintPoint); canvas.drawOval(dsb.xPos[0] - 1.2f + startX, dsb.xPos[1] - 1.2f + startY, dsb.xPos[0] + 1.2f + startX, dsb.xPos[1] + 1.2f + startY, paintPoint); else canvas.drawPoint(dsb.xPos[0] + startX, dsb.xPos[1] + startY, paintPoint); } } protected void f_putText() { // вывод сообщения в UI поток new Thread(() -> { runOnUiThread(() -> { txtSoob.setText(txtSoobColor + " " + txtSoobSelect + " " + txtSoobTouch); }); }).start(); } protected String f_getSQLForReadData(int kakRej) { // возввращает selStr - select для выбора точек по разным сортировкам - f_readData() int dimension = DbHelper.faktSubsLen; if (flagSn) { dimension = min(DbHelper.faktSubsLen_n, DbHelper.faktSubsLen); } txtSoobColor = ""; txtSoobSelect = ""; txtSoobTouch = ""; String selStr = "", tabName = flagSn ? "elements_n" : "elements" + mApp.tableNameEnd, parName = flagSn ? "pairing_area_n" : "pairing_area" + mApp.tableNameEnd, idName = flagSn ? "id_true" : "_id", snPole = flagSn ? ", link_to_elements idgr" : ", null idgr", snWhere = flagSn ? " where for_n <= " + dimension + " " : " "; switch (kakRej) { case 1: // По итерациям selStr = "select "+ idName + " _id, substitution, iteration || ' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по итерациям"; break; case 2: // По классам selStr = "select E." + idName + " _id, E.substitution substitution, R.class_area || ' ' as kluch " + snPole + ", E.ciklos ciklos " + " from " + tabName + " E, " + parName + " R" + " where R.id_subs = E." + idName + (flagSn ? " and for_n <= " + DbHelper.faktSubsLen : " ") + " order by kluch asc"; txtSoobColor = "Раскраска точек по классам"; break; case 6: // По цикл типу selStr = "select " + idName + " _id, substitution, cykl_len as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по цикл типу"; break; case 4: // По P selStr = "select " + idName + " _id, substitution, pe || ' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по Р"; break; case 5: // По порядку эл-та selStr = "select " + idName + " _id, substitution, deg || ' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по порядку эл-та"; break; case 3: // По Силову selStr = "select " + idName + " _id, substitution, sylow_num as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по № подгруппы Силова "; break; case 7: // четные и нечетные selStr = "select " + idName + " _id, substitution, parity ||' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек четные и нечетные"; break; case 8: // по стационарным точкам select _id, substitution, length(stabilizer) ||' ' as kluch, ciklos from elements_n order by kluch asc selStr = "select " + idName + " _id, substitution, stabilizer ||' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по стационарным точкам"; break; case 9: // По числу стационарных точек selStr = "select " + idName + " _id, substitution, length(stabilizer) ||' ' as kluch " + snPole + ", ciklos from " + tabName + snWhere + " order by kluch asc"; txtSoobColor = "Раскраска точек по числу стационарных точек"; break; default: } if (DISPLAYLOG) Log.e(TAG, "f_getSQLForReadData " + DbHelper.faktSubsLen + " kakKolop = " + kakKolop + " kakRej = " + kakRej + " txtSoobColor = " + txtSoobColor +" posCreated = " + posCreated + " flagSn = " + flagSn + " sql= " + selStr); f_putText(); return selStr; } protected void startPotok() { // запустить поток для рисования paintKal = new PaintAll(this, view); paintKal.setRunning(true); paintKal.setName("paintKal"); paintKal.setPriority(1); paintKal.start(); // запустить поток // Log.d(TAG, "startPotok " ); } protected void stopPotok() {// остановить поток рисования if (paintKal != null) { if (paintKal.running.get()) { paintKal.stopPotok(); boolean retry = true; while (retry) { try {// ожидание завершение потока paintKal.join(); retry = false; } catch (InterruptedException e) { Log.d(TAG, "Error stopPotok " + e.toString()); // Toast.makeText(getApplicationContext(), "Error stopPotok " + e.toString(), //??? Toast.LENGTH_LONG).show(); } } } if (DISPLAYLOG) Log.e(TAG, "stopPotok snFlag = + snFlag "); } paintKal = null; // Log.e(TAG, "stopPotok snFlag = + snFlag "); } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { if (DISPLAYLOG) Log.d(TAG, "surfaceChanged width=" + width +" height="+ height ); IsCreat = true; repaint(); } @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { IsCreat = true; repaint(); } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { IsCreat = false; } protected void repaint() { if (DISPLAYLOG) Log.e(TAG, "repaint IsCreat = " + IsCreat + " paintKal = " + (paintKal == null) ); txtSoobColor = ""; // текст сообщения txtSoobSelect = ""; txtSoobTouch = ""; if (IsCreat) { // if (DISPLAYLOG) // Log.d(TAG, "repaint koeffX = " + koeffX ); if (paintKal == null) startPotok(); } } @Override protected void onStop( ) { super.onStop() ; if (DISPLAYLOG) Log.d(TAG, "=== onStop" ); stopPotok(); } @Override protected void onDestroy( ) { super.onDestroy(); if (DISPLAYLOG) Log.d(TAG, "=== onDestroy mSurfaceHolderActivity"); stopPotok(); if (tmr != null) { tmr.purge(); tmr.cancel(); } } @Override protected void onRestart( ) { super.onRestart() ; if (DISPLAYLOG) Log.d(TAG, "=== onRestart SurfaceHolderActivity" + " valDataRect.size= "+ valDataRect.size() + " valDataLines.size()= " + valDataLines.size()); mApp.SurfaceActivity = this; createAuto = 0; } @Override protected void onPause() { super.onPause(); stopPotok(); } @Override protected void onStart(){ super.onStart(); if (DISPLAYLOG) Log.d(TAG, "=== onStart SurfaceHolderActivity" + " valDataRect.size= "+ valDataRect.size() + " valDataLines.size()= " + valDataLines.size()); mApp.SurfaceActivity = this; } protected abstract void f_paint(); protected void f_menuSelect() { // установить флаг selectFlag по popup menu при выделении // при удалении - удаляет что затребовано // insrtStr есть insert into temp_elements (id) - таблица куда заносятся выбранные строки db.execSQL("delete from temp_pe;"); // Log.e(TAG, "f_menuSelect insrtStr= " + insrtStr); if (insrtStr.length() > 0) { db.execSQL(insrtStr); // в temp_pe id_1 = _id db.execSQL("update temp_pe set id_2 = " + menuFlg + ";" ); // сохранение при выборе ребер будет использоваться } String sqlMenu = "select id_1 || ' ' as stext from temp_pe order by 1 asc;"; int j, k, iv = valDataRect.size(), id, iSel = dbH.f_getMas(sqlMenu); if (DISPLAYLOG) Log.e(TAG, "f_menuSelect iSel = " + iSel + " iv = " + iv + " menuFlg = "+ menuFlg + " insrtStr= " + insrtStr); for (k = 0; k < iv; k++) valDataRect.get(k).selectFlag = false; for (j = 0; j < iSel; j++) { id = Integer.parseInt(DbHelper.selectedMas[j].trim()); for (k = 0; k < iv; k++) if (valDataRect.get(k).id == id) { valDataRect.get(k).selectFlag = true; break; } } if (menuFlg == 2) { // удалить все не отмеченное for (k = iv - 1; k >= 0; k--) if (! valDataRect.get(k).selectFlag) { // Log.e(TAG, "f_menuSelect remove k = " + k + " id = " + valDataRect.get(k).id + " idSub= " + valDataRect.get(k).idSub + " count= " + valDataRect.size()); valDataRect.remove(k); } else { valDataRect.get(k).selectFlag = false; } } if (DISPLAYLOG) Log.e(TAG, "f_menuSelect count= " +valDataRect.size() ); if (modeGroupFlag >= 0) { txtSoobSelect = classKely.valuesTextForSelect[modeGroupFlag] + " " + modelGroupNum; f_putText(); } } protected void f_elementSelect() { // установить флаг selectFlag по popup menu при выделении по ModeActivitySize // temp_pe (id) - таблица где записаны выбранные строки String sqlMenu = "select id_1 || ' ' as stext from temp_pe order by 1 asc;"; int j, k, iv = valDataRect.size(), id, iSel = dbH.f_getMas(sqlMenu); if (DISPLAYLOG) Log.e(TAG, "f_elementSelect iSel = " + iSel + " iv = " + iv + " menuFlg = " + menuFlg ); for (k = 0; k < iv; k++) valDataRect.get(k).selectFlag = false; for (j = 0; j < iSel; j++) { id = Integer.parseInt(DbHelper.selectedMas[j].trim()); // if (DISPLAYLOG) // Log.e(TAG, "f_elementSelect id = " + id); for (k = 0; k < iv; k++) if (valDataRect.get(k).id == id) { valDataRect.get(k).selectFlag = true; break; } } } private class PaintAll extends Thread { private final SurfaceHolderActivity activity; private final SurfaceView view; volatile AtomicBoolean running; public PaintAll(SurfaceHolderActivity cActivity, SurfaceView view) { activity = cActivity; this.view = view; running = new AtomicBoolean(); running.set(false); } /* состояния потока*/ public void setRunning(boolean run) { running.set(run); } /* в потоке */ public void run() { // Log.d(TAG, "***start run() " ); while (running.get()) { if (isInterrupted()) return; canvas = null; // своя ссылка на канву try { // подготовка Canvasа canvas = view.getHolder().lockCanvas(); synchronized (view.getHolder()) { activity.f_paint(); // собственно рисование } } catch (Exception e) { StackTraceElement ste[] = e.getStackTrace(); Log.d(TAG, "***Error " + e.toString() + " running=" + running.get()); for (int i = 0; i < ste.length; i++) Log.d(TAG, "***Error " + i + " " + ste[i].getMethodName() + " line " + ste[i].getLineNumber()); // Toast.makeText(activity, "Error" + e.toString() +" "+activity.buildStep+ " "+ activity.IsKaleydoskop.get()+" running="+running.get() + " "+e.getStackTrace(), Toast.LENGTH_SHORT).show(); } finally { // try закончился if (canvas != null) { view.getHolder().unlockCanvasAndPost(canvas); } } } } public void stopPotok() { //прервать рисование running.set(false); // текущая итерация - последняя this.interrupt(); // и заканчивается она прямо сейчас } } } //--------------------------